是否pg_prepare()准备语句(不PDO)防止SQL注入?(Does pg_prepare()

2019-06-26 22:49发布

PDO IST不是在目标系统不支持我的工作虽然我寻求防止使用PHP的5.1.x SQL注入上一个Postgres-DB 8.2或以上版本的解决方案。 有目前没有切换到PDO机会。

我目前的解决方案是pg_prepare准备语句:

// 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");
}

但pg_prepare的文档缺少有关的重要信息:

它讲述了“以后使用”

pg_prepare()创建用于与pg_execute)以后执行(或pg_send_execute()准备好的语句。[...]

它讲述了“命名的/匿名发言”

该函数创建一个名为从查询字符串stmtname一份声明,其中必须包含一个SQL命令。 stmtname可以是“”创建一个无名语句,在这种情况下任何预先存在的未命名的语句被自动替换; [...]

它讲述了“类型转换”

与pg_prepare使用预准备语句()也可以通过执行SQL创建准备的语句。 (但pg_prepare()更灵活,因为它不要求预先指定的参数类型。)此外,虽然有删除一个准备好的声明中没有PHP函数时,SQL DEALLOCATE语句可以用于这一目的。

但它并没有告诉,如果此实现准备好的语句是安全的从SQL注入

*几乎所有的评论此安全问题是指PDO的解决方案,在文档其中注意到,驱动程序会阻止SQL注入。 但是,如果一个简单的解决方案,可以pg_prepare,我就在此刻使用pg_prepare。*

感谢也许是最佳实践的解决方案的这一重要信息。

编辑(后标记为解决方案):谢谢你很有启发的答案!

  • 标志着我坦率Heikens的解决方案为最佳答案,因为它解释了SQL注入的一个重要点。 程序员可以使用准备好的statemtents,但SQL注入,缺乏仍可能错在那里!
  • 除了弗兰克Heikens答案,hoppa表明SQL注入使用pg_prepare / pg_query_params防止。 谢谢您的好意。
  • 现在将使用优化的代码pg_query_params (感谢米伦A.拉德夫)
  • 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');
}

Answer 1:

预准备语句是从SQL注入安全的,因为它的准备后,任何人都无法改变的queryplan。 但是,如果你的发言已经被损害,你还是从SQL注入苦:

<?php 
// how NOT to construct your SQL....
$query = 'SELECT * FROM user WHERE login=$1 and password=md5($2) LIMIT '. $_POST['limit']; -- injection!
$result = pg_prepare($dbconn, "", $query);
$result = pg_execute($dbconn, "", array($_POST["user"], $_POST["password"]));
if (pg_num_rows($result) < 1) {
  die ("failure");
}
?>


Answer 2:

预处理语句是内置到MySQL( http://dev.mysql.com/doc/refman/5.6/en/sql-syntax-prepared-statements.html )。 注射预防机制也是在MySQL中,看到这句话从以前链接的页面:

防止SQL注入攻击。 该参数值可以包含转义SQL引号和分隔符。

PHP库都只是他们的映射功能,MySQL的功能(可能使用http://docs.oracle.com/cd/E17952_01/refman-5.0-en/c-api-prepared-statement-function-overview.html )。 所以,是的,pg_prepare还应保护您注射。

[编辑]我只注意到你在谈论的PostgreSQL,PostgreSQL的也是一样,它是一个内置的语言特性 ,不是一个PHP库提供。



Answer 3:

至于我可以从文档收集它应该保护你对SQL注入。

一个更通用的方法是使用pg_query_params因为它不准备查询连接。



Answer 4:

使用准备好的语句通常是去了,因为你也应该从可被忽略的数据库的优化更好的SQL性能的最佳方式。

然而,它是一件好事,知道做事的替代方法,因此请您记住,你可以使用pg_escape_string()在你的污点变量,然后直接在SQL查询中使用输出。



文章来源: Does pg_prepare() prepared statement (not PDO) prevent SQL-Injection?