php中的sql防注入
1 addslashes()方法对参数预处理
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符有
- 单引号(')
- 双引号(")
- 反斜杠(\)
- NULL
存在问题
addslashes 函数仅仅是将某些字符进行了转义,但并没有考虑到不同字符集的编码问题。因此,在使用 addslashes 函数时,可能会出现以下情况:
-
如果使用的是非 ASCII 字符集,如中文、日语等字符集,那么 addslashes 函数可能会导致字符串变得无效或者出现乱码。
-
addslashes 函数并不能转义所有可能引起 SQL 注入的字符。例如,使用 %、_、- 等字符可以进行模糊查询,而这些字符在 addslashes 函数中并没有被转义。
-
addslashes 函数并不能防止双重转义问题。如果用户已经对输入进行了转义,再使用 addslashes 函数可能会导致出现双重转义的问题,从而使字符串变得无效。
2 使用mysqli_real_escape_string()函数转义
$username = mysqli_real_escape_string($conn, $_POST['username']);
$password = mysqli_real_escape_string($conn, $_POST['password']);
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
$result = mysqli_query($conn, $sql);
3 使用参数化查询 (Prepared Statements) 或者绑定参数(Binding Parameters)的方法
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->execute([$username, $password]);
为什么预处理和参数化查询可以防止sql注入呢?
在mysql5.1后,提供了类似于jdbc的预处理-参数化查询。它的查询方法是:
a. 先预发送一个sql模板过去
b. 再向mysql发送需要查询的参数
发送的参数会自动过滤用户输入中的特殊字符