今天就跟大家聊聊有关MySQL注入在PHP代码层面的防御手段是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:申请域名、网络空间、营销软件、网站建设、松北网站维护、网站推广。
什么是sql注入?
服务端没有对用户提交的参数进行严格的过滤,导致可以将SQL语句插入到可控参数中,改变原有的SQL语义结构,从而执行攻击者所预期的结果。
sql注入的探测
判断数据库类型
端口
报错信息
一些中间件常用的数据库
PHP MySQL
ASP SQL Server
ASPX SQL Server
JSP MySQL Oracle
寻找SQL注入点
寻找与数据库交互的可控参数
GET
POST
COOKIE
HTTP头
确定注入点
确定注入点的核心思想就是判断插入的数据是否被当做SQL语句执行。可以使用简单的算术运算来测试。
SQL语句预编译和绑定变量
使用足够严格的过滤和安全防御
Web应用向数据库传递语句模板
数据库对模板进行编译,编译以后语义将不会改变
变量绑定,Web应用向数据库传递变量,变量只会被当做数据识别,不会被作为语义结构识别
执行SQL语句
SQL注入的核心:数据和代码的混淆。
什么是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,则会存在宽字节+堆叠注入的双重漏洞。
对于此类问题的防范,主要有以下三个方面:
合理、安全的使用gbk编码。即使采用PDO预编译的方式,如果开启模拟预编译,依然可以造成宽字节注入。
使用PDO时,一定要将模拟预编译设置为false。
可采用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 是一种应用程序编程接口(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函数允许你访问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' ) );
看完上述内容,你们对mysql注入在PHP代码层面的防御手段是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。