PHP 项目中单独使用 Laravel Eloquent 查询语句来避免 SQL 注入

file

OWASP (Open Web Application Security Project) 是一个记录当前 web 应用所受威胁状况的项目。我一直都在关注他们的网站,从 2010,2013 和 2017 年的报告中我发现了一些类似之处,SQL 或其余类型的注入威胁都是高居榜首。php

这是个心腹大患。mysql

它会致使你破产,所以这个事情关乎存亡,你单位应该着力处理此类问题避免它的出现。laravel

什么是注入?

所谓注入,就是数据没有通过过滤,将没法信任的内容直接写入了系统解释器,这种行为会致使对站点产生SQL注入,更糟糕的是,攻击者可能会得到对系统的所有权限。web

举个例子:

看下面的恶意查询语句,它会将含有恶意行为的SQL语句放在$name变量里,而后容许用户经过POST的方式传递给PHP脚本,从而达到最终使用传入的恶意代码进行攻击的目的。sql

//将恶意代码, DROP TABLE写入$name变量
`$name = "Mark';DROP TABLE users; -- ";\
$query = "SELECT * FROM users WHERE name='$name'";`数据库

通过PHP脚本解析,这会最终生成这样的SQL语句:
SELECT * FROM users WHERE name='Mark';DROP TABLE users; -- 'json

正如你猜的那样,上述语句会将整个users数据表从数据库里删除掉。安全

正如尤达说的:composer

这太危险了,是的,太危险了。

如何防止对 PHP 应用的恶意注入?

首先,其实并无真的往数据库里注入什么东西,这种错误只是因为没有正确地将查询语句格式化。解决的方法很简单,只要正确地格式化 SQL 语句,或者是直接把查询语句和数据分开处理。框架

怎么作呢?用参数化查询对数据格式化,并使查询语句与数据分离。

使用参数化查询,能够确保程序远离注入风险。

例子以下:

`$statement = $db->prepare('SELECT * FROM table WHERE id = ? and name = ? ');\
$statement->execute([1, "Mark"]);`

除此以外,还有一种安全的作法,就是在项目中使用 ORM ( 对象关系映射)或者是查询构造器。

我要推荐的是著名的 PHP 框架 Laravel 也在用的 Eloquent。接下来,我会教你如何安装和使用,它能够帮助咱们作好数据格式化的工做,从而有效避免注入危害。

更多关于 Eloquent 知识能够参考 laravel docs.

安装 Eloquent

准备工做

请确保你已经安装了 PHP 和 Composer

正式开始

最好在项目开始之初就安装 ORM。

假设咱们想建一个博客应用,包含一个 posts 表和一个 users 表。

初始化配置

首先要作的是为程序建立 composer.json 文件。 你能够在终端上运行 composer init  并按照终端上的提示进行操做。

eloquent composer setup screenshot

当他要求您来定义依赖关系的时候, 写入 illuminate/database . 最后的输出应该和上面的图片中显示的同样。如今你就能够在项中经过运行  composer install  来安装相应的依赖了。

或者,若是你已经有了 composer.json 这个文件, 你能够直接在终端输入  composer require illuminate/database 来安装相应的依赖。

如今咱们须要在应用程序的根目录中建立  start.php 文件并把下面的代码粘贴到文件中。我会在下面解释他们的做用。

require "vendor/autoload.php";
//If you want the errors to be shown  *是否显示错误
error_reporting(E_ALL);
ini_set('display_errors', '1');
use Illuminate\Database\Capsule\Manager as Capsule;

 $capsule = new Capsule;

 $capsule->addConnection([
    "driver" => "mysql",
    "host" =>"127.0.0.1",
    "database" => "test",
    "username" => "root",
    "password" => "root"
 ]);
//Make this Capsule instance available globally. *要让 capsule 能在全局使用
 $capsule->setAsGlobal();
// Setup the Eloquent ORM.
 $capsule->bootEloquent();

在第一行咱们须要引入 vendor/autoload.php 文件。这样咱们才能加载到 vendor 目录下的全部包。

而后咱们引入 use Illuminate\Database\Capsule\Manager as Capsule 并起别名 ,这样子咱们就能使用 eloquent 了。

接下来, 咱们建立一个 Capsule 对象并初始化咱们的数据库链接, 如上  bootEloquent() 。

如今, 很明显咱们要作的第一件事就是建立名为 test 的数据库,请确保你在本身本地输入的是正确的用户名和密码.

Migrations / 数据迁移

使用 Eloquent 的一个最大的好处就是可使用 migrations。

若是你不了解什么是 migrations,能够看下面的解释:

migration 是一种能够经过 PHP 代码建立数据表的方式。

migrations.php 文件中建立 migration:

require "start.php";
use Illuminate\Database\Capsule\Manager as Capsule;
Capsule::schema()->create('users', function ($table) {
   $table->increments('id');
   $table->string('name');
   $table->string('email')->unique();
   $table->string('password');
   $table->timestamps();
});
Capsule::schema()->create('posts', function ($table) {
   $table->increments('id');
   $table->string('title');
   $table->text('body');
   $table->integer('created_by')->unsigned();
   $table->timestamps();
});

上面这段代码,经过 Capsule 类建立了两个数据表,一个是 users 表,另外一个是 posts 表,而且分别为他们定义了字段名。

运行这个文件,若是你看到白屏,就说明 migrations 运行成功了,如今就能够打开数据库看看是否生成了这两个表。

php myadmin models example

Models

如今,惟一要作的就是建立对应数据表的 Model 类。

用了 Eloquent,你就能够在 Model 类里操做相应的数据表,执行查询语句了。

建立一个 Models 文件夹,而后在其中分别建立 User.phpPost.php 文件:

namespace Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
   /**
    * 对应的数据表
    *
    * @var string
    */
    protected $table = "users";
   /**
    * 容许插入的字段
    *
    * @var array
    */
    protected $fillable = [
        'name', 'email', 'password'
    ];
   /**
    * 须要被隐藏的字段
    *
    * @var array
    */
    protected $hidden = [
        'password', 'remember_token',
    ];
   /*
    * 给 User 类添加方法
    *
    */
    public function posts()
    {
        return $this->hasMany(Post::class, 'created_by');
    }
}

And

namespace Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
   /**
    * 对应的数据表
    *
    * @var string
    */
    protected $table = "posts";
  /**
   * 容许插入的字段
   *
   * @var array
   */
   protected $fillable = [
       'title', 'body', 'created_by'
   ];
 }

composer.json 文件中加入以下代码,以确保上面建立的类文件可以被自动加载。

"autoload": {
    "classmap": [
        "Models" // Folder where all your models are
     ]
}

而后执行 composer dump-autoload

经过 Eloquent 操做数据库

基本大功告成了。 测一下吧,在根目录建立 index.php 文件,添加以下代码:

require "start.php";
use Models\User;
use Models\Post;
User::create(
 [
  'name' => 'Mark Mike',
  'email' => 'temp-email-1@mark.com',
  'password' => '1234'
 ]
);
Post::create(
 [
  'title' => 'New Blog Post',
  'body' => 'New Blog Content',
  'created_by' => 1
 ]
);
print_r(User::all());
print_r(Post::all());
print_r(User::find(1)->posts);

如你所见,用 Eloquent 操做数据库就是这么简单。除此以外,Eloquent 还提供了不少方法供你使用,并且很安全。

结语:

Eloquent 就像是给你的 SQL 查询加了一道安全层,它能够过滤掉咱们在执行 SQL 查询时所犯的错误。若是你想用它,可是又不想安装 Laravel 框架,那么我想你已经从这篇文章中学到了该如何去作。这个优雅的 SQL 助手,将帮助你写出更干净且更安全的代码。

文章转自: https://learnku.com/php/t/25962

更多文章: https://learnku.com/php/c/tra...
相关文章
相关标签/搜索