SQL注入的防范
目录
一 . 代码层防御
在web应用中,又存在着通过拼装用户操作参数的sql语言进行查询数据库,将结果返回用户。如果在这个过程中,处理不当,也就是防护不够到位,会出现SQL注入这样的漏洞
例如: select * from table where id = ${id}
我们把这个条件从1换成 1 or 1 = 1 即得到:
Select * from table where id = 1 or 1 = 1 ; 从原本的语 义变换成不严谨的SQL语言
再比如: select * from user where username = '${data.username}' and password = '${data.password}'
这时候,我们通过传值,把password变更为:1' or '1' = '1
select * from user where username = 'johnny' and password = '1' or '1' = '1'
最后的or把前面的条件给否定了,此时用户名和密码完全没用了。所以在我看来,学习SQL注入的目的不只是学习针对这种方法,而失去举一反三,学习一类方法,简单的来说SQL注入就是在人为可以构造参数的的地方加入一些非法敏感语句,绕过后端的处理,然后带入数据库中执行,然后返回敏感数据的过程。
1.使用参数化语句
我们知道,SQL注入最根本的原因之一就是把SQL查询创建成字符串然后发给数据库执行,这一行为是最容易受到SQL注入攻击的主要原因之一。
作为一种更加安全的当天字符串构造方法,大多数现代编程语言和数据库访问API可以使用占位符或者绑定变量来向SQL查询提供参数,这并非是直接对用户输入进行操作的。统称为参数化语句。
1.1使用PHP语句将基本SQL语句参数化处理
PHP同样包含很多用于访问数据库的框架,现最常见的框架:访问MySQL数据库的musqli包,PEAR::MDB2包,和新的PHP数据对象(PDO)框架,均为使用参数化语句提供便利。
Mysqli包括与PHP 5.x ,可以访问MySQL4.1及以后的版本,是最常用的数据库接口之一,通过使用问号占位符来支持参数化语句
例如:
$con = new mysqli (“localhost”,”username”,”password”,”db“);
$sql = “SELECT * FROM users Where username=? AND password=?”;
$cmd = $con->prepare($sql);
//Add parameters to SQL query
$cmd->bind_param(“ss”, $username, $password); //bind parameters as strings
$cmd->execute();
-
- 使用PDO包包含在PHP 5.1 及之后的版本中。 他是一个面向对象且独立于供应商的数据层,用于访问数据库。PDO支持使用冒号字符和问号占位符两种方式来命名参数。
例如:
$sql =” SELECT * FROM uses WHERE username=;uswename AND” + “passwoed=:password”;
$stme = $dbh->prepare($sql);
//bind values and data types
$stmt->bindParam(‘:username’,$username, PDO::PARAM_STR,12);
$stmt->bindParam(‘:password’,$password, PDO::PARAM_STR,12);
$stmt->execute();
-
-
PHP中的输入验证
-
PHP不直接依赖表面层,因为PHP中的输入验证支持和Java中极其相似,都是专属于所使用的框架。所以我们可以使用PHP中的很多函数来作为构造输入验证的基本构造块
- preg_match(regex,matchstring): 使用正则表达式regex对 matchstring 做正则表达式相匹配
- is_<type>(input): 检查输入是否为<type>, 例如is_numeric().
- 检查函数strlen(input): 检查函数检查输入的长度
使用preg_match验证表单参数如下例:
$username = $_POST[ ‘username’]
If (!preg_match(“/^[a-zA-z] {8,12}$/D”, $username) {
/ / handle failer validation
}