我了解到使用预准备语句(参数化查询)可用于防止SQL注入攻击,本文中提到的例外情况很少:Are PDO prepared statements sufficient to prevent SQL injection?。
我的问题是预备语句如何阻止SQL注入?到目前为止我学到了什么:
使用参数化查询时,客户端将查询发送到服务器进行准备(优化),不需要任何数据,稍后,参数(用户输入或任何)将被发送到服务器,以便用户数据驻留在外部原始查询。
使用准备好的查询时,如果未转义用户数据,则不会阻止任何SQL注入。
出于这个原因,我没有测试该示例,因为使用execute()
,bind_param()
,binVlaue()
,binParam()
都在使用时转义数据,以便我们可以' t与他们一起发送未转义的数据,以测试带有未转义参数的预准备报表的安全性。
答案 0 :(得分:4)
基本问题是:
$value = "Foo' OR 1 = 1 --";
$query = "SELECT id FROM users WHERE name = '$value'";
如上连接,这是实际的查询:
SELECT id FROM users WHERE name = 'Foo' OR 1 = 1 --'
这里的问题是字符'
,它在字符串文字上下文中具有终止字符串文字的特殊含义。
处理此问题的一种方法是转义字符,这些字符在字符串文字中具有特殊含义:
SELECT id FROM users WHERE name = 'Foo\' OR 1 = 1 --'
另一种方法是将字符串文字完全分开,因此不会混淆它的起点和终点:
query: SELECT id FROM users WHERE name = $1
$1: Foo' OR 1 = 1 --
前一种技术是转义,后者是参数化查询。您只需要使用其中一个。如果你转义了你也参数化的值,你只需要用不必要的反斜杠来搞乱你的值。
答案 1 :(得分:2)
SQL注入意味着用户输入用作SQL语句的一部分。
如果您使用预准备语句,则用户输入将被视为内容而不是SQL命令的一部分。
但是,如果通过将用户输入字符串连接在一起来构建SQL命令,那么再次引入SQL注入漏洞。
因此,简而言之,使用准备好的查询是安全的,但用户输入应仅用作参数,而不是查询文本的一部分。
答案 2 :(得分:0)
是的,您可以通过pdo和mysqli
阻止sql注入使用PDO:
步骤1:连接数据库
在这里我创建数据库“inphplab”。您可以根据自己的要求进行更改。
$dbConnection = new PDO('mysql:dbname=inphplab;host=127.0.0.1;charset=utf8', 'root', '');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
步骤2:将数据插入“员工”表
这里我采取两个变量并声明姓名和地址如下。
$name = "bapuRocks";
$address = "India";
$stmt = $dbConnection->prepare("INSERT INTO employee ( name, address) VALUES ( :name, :address )");
$stmt->bindValue(':name', $name);
$stmt->bindValue(':address', $address);
printf("%s Row inserted.\n", $stmt->execute());
使用MySQLi:
步骤1:连接数据库
在这里我创建数据库“inphplab”。您可以根据自己的要求进行更改。
$mysqli = new mysqli('localhost', 'root', '', 'inphplab');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
步骤2:将数据插入/删除到“员工”表
这里我采取两个变量并声明姓名和地址如下。
$stmt = $mysqli->prepare("INSERT INTO employee SET `name`=?,`address`=?");
$stmt->bind_param('ss', $name, $address);
$name = 'Yuvraj Sinh';
$address = 'India';
/* execute prepared statement */
$stmt->execute();
printf("%s Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();
/* Clean up table CountryLanguage */
$mysqli->query("DELETE FROM employee WHERE name='Bharat Sinh'");
printf("%s Row deleted.\n", $mysqli->affected_rows);
/* close connection */
$mysqli->close();
答案 3 :(得分:0)
防止SQL注入的最简单方法是使用简单的hex2str()
函数将所有用户输入转换为HEX,然后使用str2hex()
将其转换回来 - 这可确保所有数据都是安全的。
function strToHex($string){
$hex = '';
for ($i=0; $i<strlen($string); $i++){
$ord = ord($string[$i]);
$hexCode = dechex($ord);
$hex .= substr('0'.$hexCode, -2);
}
return strToUpper($hex);
}
function hexToStr($hex){
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2){
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
$ID = strToHex($_GET["ID"]);
$COL1 = strToHex($_GET["COL1"]);
$COL2 = strToHex($_GET["COL2"]);
$query = "insert into my_db.my_table(ID, COL1, COL2) VALUES('$ID','$COL1','$COL2')";
简单就是那个