mysql注入在PHP代码层面的防御手段

访客4年前黑客文章1073

前置知识

什么是sql注入?

服务端没有对用户提交的参数进行严格的过滤,导致可以将SQL语句插入到可控参数中,改变原有的SQL语义结构,从而执行攻击者所预期的结果。

sql注入的探测

判断数据库类型

  • 端口

  • 报错信息

一些中间件常用的数据库

寻找SQL注入点

寻找与数据库交互的可控参数

  • GET

  • POST

  • COOKIE

  • HTTP头

确定注入点

确定注入点的核心思想就是判断插入的数据是否被当做SQL语句执行。可以使用简单的算术运算来测试。

SQL注入的防御的原理

  • SQL语句预编译绑定变量

  • 使用足够严格的过滤和安全防御

  1. Web应用向数据库传递语句模板

  2. 数据库对模板进行编译,编译以后语义将不会改变

  3. 变量绑定,Web应用向数据库传递变量,变量只会被当做数据识别,不会被作为语义结构识别

  4. 执行SQL语句

SQL注入的核心:数据和代码的混淆。

PDO

什么是PDO?

PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口。

PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数( *** )来查询和获取数据。

PDO是php中最典型的预编译查询方式。

PDO场景下的SQL注入

PDO与安全相关的问题主要的设置有下面三项:

PDO::ATTR_EMULATE_PREPARES  # 模拟预编译
PDO::ATTR_ERRMODE # 报错
PDO::MYSQL_ATTR_MULTI_STATEMENTS # 多语句执行

之一项为模拟预编译,如果为False,则不存在SQL注入;如果为True,则PDO并非真正的预编译,而是将输入统一转化为字符型,并转义特殊字符。这样如果是gbk编码则存在宽字节注入。

第二项而报错,如果设置为True,可能会泄露一些信息。

第三项为多语句执行,如果设置为True,且之一项也为True,则会存在宽字节+堆叠注入的双重漏洞。

对于此类问题的防范,主要有以下三个方面:

  1. 合理、安全的使用gbk编码。即使采用PDO预编译的方式,如果开启模拟预编译,依然可以造成宽字节注入。

  2. 使用PDO时,一定要将模拟预编译设置为false。

  3. 可采用Prepare Statement手动预编译,防御SQL注入。

代码示例

$dbh=new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password);
$stmt=$dbh->prepare('INSERT INTO REGISTRY (name, value) VALUES (:name, :value)');
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name='one';
$value=1;
$stmt->execute();

或者

$dbh=new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password);
$stmt=$dbh->prepare('UPDATE people SET name=:new_name WHERE id=:id');
$stmt->execute( array('new_name'=> $name, 'id'=> $id) );

详细请参考:

从宽字节注入认识PDO的原理和正确使用

SQL注入基础整理及Tricks总结

技术分享 | MySQL 注入攻击与防御


ODBC

ODBC 是一种应用程序编程接口(Application Programming Interface,API),使我们有能力连接到某个数据源(比如一个 MS Access 数据库)。

代码示例

$stmt=odbc_prepare( $conn, 'SELECT * FROM users WHERE email=?' );
$success=odbc_execute( $stmt, array($email) );

或者

$dbh=odbc_exec($conn, 'SELECT * FROM users WHERE email=?', array($email));
$sth=$dbh->prepare('SELECT * FROM users WHERE email=:email');
$sth->execute(array(':email'=> $email));

MYSQLi

MySQLi函数允许你访问MySQL数据库服务器。

$stmt=$db->prepare('update name set name=? where id=?');
$stmt->bind_param('si',$name,$id);
$stmt->execute();

框架

对于框架的话只要遵循框架的API就好,例如wp查询

global $wpdb;
$wpdb->query(
$wpdb->prepare( 'SELECT name FROM people WHERE id=%d OR email=%s',
$person_id, $person_email
)
);
global $wpdb;
$wpdb->insert( 'people',
array(
'person_id'=> '123',
'person_email'=> 'bobby@tables.com'
),
array( '%d', '%s' )
);

相关文章

饶宗颐学术馆

饒宗頤學術館讀書啊,我信赖但有朗朗書聲出破廬,遲早有一日有萬鯉躍龍門之奇象。 《戊戌年仲夏回鄉探親遊記》 頤園…饒宗頤學術館,位於潮州古城韓江邊,毗鄰中國四大古橋之一的廣濟橋,是一處融庭園景...

在家怎么赚钱现实点的(最简单靠谱的十种赚钱

在家怎么赚钱现实点的(最简单靠谱的十种赚钱

如今,时代在进步和发展。随着互联网的发展,很多朋友希望在业余时间通过使用互联网来赚取更多的收入,但是因为他们不了解,经常被欺骗,他们中的大多数人不能相信很多项目可以赚钱。今天,新娘将和她的朋友们分享她...

era徐可个人资料(人物经历、背景)

era徐可个人资料(人物经历、背景)

作为一名95后创业者,上海讯踪信息科技有限公司CEO,价值技能社交App ERA创始人徐可最近一直被人所关注着。无论是在电视节目里、新闻报道中,还是在微博上,这一位95年出生的女生都毫不遮掩地表达...

地摊早餐适合做什么好(摆摊卖早餐卖什么比较

地摊早餐适合做什么好(摆摊卖早餐卖什么比较

对于摆摊创业 买早餐是很好的一个选择方式,到时什么样的早餐消费者更喜欢呢。许多人就为早餐发愁:上哪儿去吃早餐、早餐吃什么?早餐小吃学做什么能摆摊卖的,一个或两个人就可以操作,简单点的,下面跟随食为先小...

用户运营:用户分级必不可少(一)

用户运营:用户分级必不可少(一)

最近的一些事情内容较量频繁的涉及用户体系的构建,于是在这篇文章里举办梳理;也但愿以此为系列文章的开头,抛砖引玉,谈谈用户运营顶用户分级的相关常识。 用户运营,是所有运营岗亭所必须的模块常识,因为所有的...

马云:我已经知道自己的结局了-马云四号以后就没有露面-马云不把省委

马云:我已经知道自己的结局了-马云四号以后就没有露面-马云不把省委

前不久大伙儿有注意到马云爸爸被提醒谈话,小蚂蚁集团公司发售被喊停,因而很多人都很好奇马云爸爸近期是产生什么事情了,据统计马云爸爸四号之后就沒有出面,而且在先前马云爸爸:我已经了解自身的结果了,那麼到底...