PHP 项目中单独使用 Laravel Eloquent 查询语句来避免 SQL 注入
OWASP (Open Web Application Security Project) 是一个记录当前 web 应用所受威胁情况的项目。我一直都在关注他们的网站,从 2010,2013 和 2017 年的报告中我发现了一些相似之处,SQL 或其他类型的注入威胁都是高居榜首。
这是个心腹大患。
它会导致你破产,因此这个事情关乎存亡,你单位应该着力处理此类问题避免它的出现。
什么是注入?
所谓注入,就是数据没有经过过滤,将无法信任的内容直接写入了系统解释器,这种行为会导致对站点产生SQL注入,更糟糕的是,攻击者可能会获得对系统的全部权限。
举个例子:
看下面的恶意查询语句,它会将含有恶意行为的SQL语句放在$name
变量里,然后允许用户通过POST
的方式传递给PHP脚本,从而达到最终使用传入的恶意代码进行攻击的目的。
*//将恶意代码, DROP TABLE写入name = "Mark';DROP TABLE users; -- ";
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 知识可以参考 laravel docs.
安装 Eloquent
准备工作
请确保你已经安装了 PHP 和 Composer。
正式开始
最好在项目开始之初就安装 ORM。
假设我们想建一个博客应用,包含一个 posts 表和一个 users 表。
初始化配置
首先要做的是为程序创建 composer.json 文件。 你可以在终端上运行 composer init
并按照终端上的提示进行操作。
当他要求您来定义依赖关系的时候, 写入 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 运行成功了,现在就可以打开数据库看看是否生成了这两个表。
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');}
}
复制代码
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 助手,将帮助你写出更干净且更安全的代码。
文章转自:learnku.com/php/t/25962
更多文章:learnku.com/php/c/trans…
转载于:https://juejin.im/post/5c984181f265da610a56f4a7
PHP 项目中单独使用 Laravel Eloquent 查询语句来避免 SQL 注入相关推荐
- laravel mysql注入_PHP 项目中单独使用 Laravel Eloquent 查询语句来避免 SQL 注入
OWASP (Open Web Application Security Project) 是一个记录当前 web 应用所受威胁情况的项目.我一直都在关注他们的网站,从 2010,2013 和 201 ...
- 在MySQL中,一条查询语句是如何执行的
MySQL 基本架构示意图 大体来说,MySQL 可以分为 Server 层和存储引擎层两部分: Server 层 包括连接器.查询缓存.分析器.优化器.执行器等,涵盖 MySQL 的大多数核心服务功 ...
- R语言构建仿真数据库(sqlite)并使用dplyr语法和SQL语法查询数据库、将dplyr语法查询语句翻译为SQL查询语句
R语言构建仿真数据库(sqlite)并使用dplyr语法和SQL语法查询数据库.将dplyr语法查询语句翻译为SQL查询语句 目录
- MySQL中的常见子查询语句
一.子查询语句格式 基本语法:SELECT 字段列表/* + FROM + 表名 +[WHERE 条件]; 完整语法:SELECT [SELECT 选项] + 字段列表[字段别名] /* + FROM ...
- 为什么只能sudo进mysql_解决项目中MySQL数据库执行删除语句时间太长的问题
问题描述: 由于业务需求,需要删除一些重复数据.即删除openid对应的2条数据,最终只保留一行. MySQL数据库,sql语句比较简单:删除数据前,备份数据是必须的! 先来错误的演示: 1.先把错误 ...
- php 中 sql 查询语句怎么写,sql查询语句有哪些
sql查询语句:1.查看表结构[SQL>DESC emp]:2.查询所有列[SQL>SELECT * FROM emp]:3.查询指定列:4.查询指定行:5.使用算术表达式:6.使用逻辑操 ...
- SQLServer中常用的分页查询语句
前言 在SqlServer中,分页查询是经常用到的查询语句,一个好的分页查询语句,不仅能将代码省略,还能提高运行效率,下面我们来探讨一下SQLServer中的分页查询语句. 具体的业务逻辑是这样的,我 ...
- mysql delete语句非常耗时_解决项目中MySQL数据库执行删除语句时间太长的问题
问题描述: 由于业务需求,需要删除一些重复数据.即删除openid对应的2条数据,最终只保留一行. MySQL数据库,sql语句比较简单:删除数据前,备份数据是必须的! 先来错误的演示: 1.先把错误 ...
- mysql中多表联合查询语句_mysql中的多表联合查询语句是什么
mysql中的多表联合查询语句是:[select 语句1 union [union 选项] select 语句2 union [union 选项] select 语句n].多表联合查询结果是将多个se ...
最新文章
- C++中虚函数可以是内联函数吗?
- Android模拟器环境下SD卡内容的管理[转]
- Android 通过onTouchEvent判断是否为双击事件
- 示波器测ab相_独有功能,剑走偏锋,示波器鲜为人知的10大特异功能|测试能力篇...
- raid卡组不同raid_RAID有哪几种?有什么区别?
- SAP UI5 应用开发教程之五十七 - 基于 OData 注解的 Smart Field 使用方法学习试读版
- 浅谈 SQL Server 内部运行机制
- Android之运行的错误:java.lang.UnsatisfiedLinkError: Couldn‘t find cibloger.so
- [Web Chart系列之五] 1. 实战draw2d 之总体介绍
- 凸优化第八章几何问题 8.4极值体积椭圆
- mysql SQL语句分析工具_MySQL 数据库中SQL语句执行分析优化工具Explain使用说明 | IT工程师的生活足迹...
- PPT(PowerPoint)更改默认等线字体
- 软考网络工程师-华为设备命令学习笔记
- mui架构app-终章(我是怎样决定放弃mui)
- JAVA社区疫情防控系统毕业设计 开题报告
- php eregi 返回值含义,Deprecated: Function eregi() is deprecated php5.3开始不支持eregi()函数...
- [PC]极品飞车2 特别版
- 互联网史上10大经典商战
- BAT齐聚阿里安全-ASRC生态大会:呼吁联合共建网络安全白色产业链
- 006网易-表达式求值