PHP防SQL注入学习
该示例在MySQL8.0 + PHP7.3 + ThinkPHP5下操作
前提条件:
1.配置文件config.php中默认全局过滤方法
// 默认全局过滤方法 用逗号分隔多个 'default_filter' => '',
2.创建test表
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706195206.png)
3.创建test控制器
<?php namespace app\index\controller; use think\Controller; use think\Db; class Test extends Controller { public function index(){ if(input('post.')){ $data = [ 'content' => input('post.content'), ]; $result = Db::table('test')->insert($data); if($result){ dump("add suc"); } } $list = Db::table('test')->select(); $this->assign('list',$list); return $this->fetch('index/test'); } }
4.创建test模板
{include file="index/head" /} <form role="form" action="{:url('Test/index')}" method="post"> <div class="form-group"> <label>内容</label> <textarea class="form-control" name="content" rows="3"></textarea> </div> <button type="submit" class="btn btn-default">提交</button> </form> {volist name="list" id="vo"} <p>{$vo.content}</p> {/volist} </body> </html>
页面效果:
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706202823.png)
学习开始
addslashes()函数,会对单引号、双引号、反斜杠进行转义过滤
默认情况下,PHP会对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes(),如果对已转义过的字符串使用 addslashes(),会导致双层转义,所以需要借助get_magic_quotes_gpc()函数进行检测。
代码修改如下
public function index(){ if(get_magic_quotes_gpc()){ dump("open"); }else{ dump("close"); } if(input('post.')){ $data = [ 'content' => input('post.content'), ]; $result = Db::table('test')->insert($data); if($result){ dump("add suc"); } } $list = Db::table('test')->select(); $this->assign('list',$list); return $this->fetch('index/test'); }
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706200943.png)
get_magic_quotes_gpc()未开启,所以需要addslashes()过滤传参
先看没有用addslashes()过滤的传参
依次在输入框输入
‘这是一条测试语句’
“这是一条测试语句”
'这是一条测试语句'
"这是一条测试语句"
\这是一条测试语句\
数据表数据如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706203324.png)
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706203525.png)
接下来对传参过滤
$data = [
'content' => addslashes(input('post.content')),
];
重复上述传参,下面是addslashes()过滤后的效果
数据库数据展示
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706204048.png)
页面效果
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706204101.png)
htmlspecialchars() 函数 将字符 “<” (小于)和 “>” (大于)转换为 HTML 实体
先看没有用htmlspecialchars()
转义的传参效果
在输入框输入
<b>这是一条测试语句</b>
数据表数据如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706204943.png)
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706204952.png)
现在使用htmlspecialchars()
转义
$data = [
'content' => htmlspecialchars(input('post.content')),
];
数据如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706205232.png)
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706205237.png)
strip_tags() 函数 会剥去字符串中的 HTML 标签
同样先看没用strip_tags()
前的效果
输入框输入
<b>这是一条测试语句</b>
数据表如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706205623.png)
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706205636.png)
使用strip_tags()
后的效果
$data = [
'content' => strip_tags(input('post.content')),
];
数据表如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706205917.png)
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706205928.png)
nl2br() 函数 在字符串中的新行(\n)之前插入换行符
先看没用nl2br()
前的效果
输入框输入
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706210903.png)
数据表如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706210935.png)
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706210957.png)
下面是使用nl2br()
后的效果
$data = [
'content' => nl2br(input('post.content')),
];
数据表数据
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706211148.png)
页面效果
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706211134.png)
addcslashes() 函数 在指定的字符前添加反斜杠
addcslashes()
与addslashes()
作用类似,却不相同,常用在查询数据表的情况下
先在输入框输入以下参数
这是一条测试参数
这是一条测试%参数
这是一条测试_参数
数据表
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706220303.png)
页面效果
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706220313.png)
现在对上述数据进行like查询,修改代码
$list = Db::table('test')->select(); $this->assign('list',$list); $content = '测试%'; $content = '%'.$content.'%'; $search = Db::table('test')->where(['content'=>['like',$content]])->select(); $this->assign('search',$search);
{volist name="list" id="vo"}
<p>{$vo.content}</p>
{/volist}
<p>--------------------磕碜的分割线-----------------------</p>
{volist name="search" id="vo"}
<p>{$vo.content}</p>
{/volist}
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706220507.png)
本意是查找测试%的,结果却将数据表的数据全查询出来的。
//查询条件修改如下,效果依旧如上所示 $content = '%测试_%';
总之数据中存在下划线或百分号,查询数据就会出现问题
现在使用addcslashes()
重新查询
$content = '测试%'; $content = addcslashes($content,'%_'); $content = '%'.$content.'%';重新like查询
页面效果如下
![](http://runtuchigua.cn/wp-content/uploads/2021/07/QQ截图20210706221737.png)
———————————华丽的分割线————————————–
结合上面所学,创建防sql注入方法
/* * 防sql注入 */ function sql_filter($post) { // 判断magic_quotes_gpc是否为打开 if (!get_magic_quotes_gpc()) { // magic_quotes_gpc没有打开的情况对提交数据的过滤 $post = addslashes($post); } $post = addcslashes($post, '%_'); //%_过滤 $post = htmlspecialchars($post); // html标记转换 $post = nl2br($post); // 回车转换 $post = strip_tags($post); return $post; }
上述防注入方法仅供参考,还请贴合自身网站使用