PDO ist not supported in target system I'm working on 虽然我在 PostGres-DB 8.2+ 上使用 PHP 5.1.x 寻求防止SQL注入的解决方案 . 目前 no 有机会切换到PDO .
我现在的解决方案是pg_prepare-prepared声明:
// Trying to prevent SQL-Injection
$query = 'SELECT * FROM user WHERE login=$1 and password=md5($2)';
$result = pg_prepare($dbconn, "", $query);
$result = pg_execute($dbconn, "", array($_POST["user"], $_POST["password"]));
if (pg_num_rows($result) < 1) {
die ("failure");
}
But pg_prepare-documentation lacks about an important information:
it tells about "later usage"
pg_prepare()创建一个准备好的语句,以便稍后使用pg_execute()或pg_send_execute()执行 . [...]
it tells about "named/anonymous statements"
该函数从查询字符串创建名为stmtname的预准备语句,该语句必须包含单个SQL命令 . stmtname可能是“”来创建一个未命名的语句,在这种情况下,任何预先存在的未命名语句都会自动替换; [...]
it tells about "typecasting"
也可以通过执行SQL PREPARE语句来创建与pg_prepare()一起使用的预准备语句 . (但是pg_prepare()更灵活,因为它不需要预先指定参数类型 . )此外,尽管没有用于删除预准备语句的PHP函数,但SQL DEALLOCATE语句可用于此目的 .
but it does not tell, if this implementation of prepared statements is safe from SQL-injection
*此安全问题的几乎所有注释都涉及PDO解决方案,其中在文档中注意到驱动程序阻止了SQL注入 . 但如果一个简单的解决方案可能是pg_prepare,我现在会使用pg_prepare . *
感谢您提供最佳实践解决方案的重要信息 .
EDIT (after marked as solution): 感谢非常有启发性的答案!
-
我将Frank Heikens的解决方案标记为最佳答案,因为它解释了SQL注入中的一个重要点 . 程序员可能会使用准备好的状态,但SQL注入缺乏可能仍然存在错误!
-
除了Frank Heikens的回答,hoppa显示使用pg_prepare / pg_query_params阻止了SQL注入 . 谢谢 .
-
现在将使用
pg_query_params
的优化代码(感谢Milen A. Radev) -
和
pg_escape_string()
作为替代方案(感谢halfer)
所有答案都很有帮助:)
// Trying to prevent SQL-Injection (**updated**)
$sql_query = 'SELECT * FROM user WHERE login=$1 and password=md5($2);';
$result = pg_query_params($dbconn_login, $sql_query, array($_POST["user"], $_POST["password"]));
if (pg_num_rows($result) < 1) {
die('failure');
}
4 回答
准备好的语句对于SQL注入是安全的,因为没有人可以更改它准备好的查询计划 after . 但是,如果您的语句已经被破坏,您仍然会遭受SQL注入:
准备好的语句内置于MySQL(http://dev.mysql.com/doc/refman/5.6/en/sql-syntax-prepared-statements.html)中 . 注入防止机制也在MySQL中,请参阅之前链接页面的引用:
PHP库只是将它们的功能映射到MySQL函数(可能使用http://docs.oracle.com/cd/E17952_01/refman-5.0-en/c-api-prepared-statement-function-overview.html) . 所以是的,pg_prepare也应该保护你注射 .
[编辑]我刚刚注意到你在谈论PostgreSQL,对于PostgreSQL也是如此,它是内置的language feature,而不是PHP库提供的东西 .
就我从文档中收集而言,它应该防范SQL注入 .
更通用的方法是使用pg_query_params,因为它与准备查询无关 .
使用预准备语句通常是最好的方法,因为您还应该从可以跳过的数据库优化中获得更好的SQL性能 .
但是,了解其他处理方法总是好的,因此请记住,您可以在受污染的变量上使用pg_escape_string(),然后直接在SQL查询中使用输出 .