https://www.jmqz1000.com

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

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

这是个心腹大患。

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

什么是注入?

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

举个例子:

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

// 将恶意代码,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; -- '

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

正如尤达说的:

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

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

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

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

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

例子如下:

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

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

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

安装 Eloquent

准备工作

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

正式开始

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

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

初始化配置

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

fbc1f817c85fbc41e6a98a4f7feafca.png

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

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

现在我们需要在html' target='_blank'>应用程序的根目录中创建 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 运行成功了,现在就可以打开数据库看看是否生成了这两个表。

48225fdce45ec251969d2cb85a8b14c.png

Models

现在,唯一要做的就是创建对应数据表的 Model 类。

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

创建一个 Models 文件夹,然后在其中分别创建 User.php 和 Post.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');    }}Andnamespace 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 助手,将帮助你写出更干净且更安全的代码。

更多PHP相关知识,请访问PHP中文网!

以上就是在你的 PHP 项目中单独使用 Laravel Eloquent 查询语句来避免 SQL 注入的详细内容,更多请关注学知网其它相关文章!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

相关文章阅读