php – pg_prepare()预处理语句(不是PDO)是否会阻止SQL注入?

我正在研究的目标系统中不支持PDO,虽然我在PostGres-DB 8.2上寻求使用PHP 5.1.x防止sql注入的解决方案.目前没有机会切换到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");
}

但是pg_prepare-documentation缺少重要的信息:

它讲述了“以后的用法

pg_prepare() creates a prepared statement for later execution with
pg_execute() or pg_send_execute().[…]

它讲述了“命名/匿名陈述”

The function creates a prepared statement named stmtname from the
query string, which must contain a single sql command. stmtname may be
“” to create an unnamed statement, in which case any pre-existing
unnamed statement is automatically replaced;[…]

它讲述了“类型转换”

Prepared statements for use with pg_prepare() can also be created by
executing sql PREPARE statements. (But pg_prepare() is more flexible
since it does not require parameter types to be pre-specified.) Also,
although there is no PHP function for deleting a prepared statement,
the sql DEALLOCATE statement can be used for that purpose.

但是它没有说明,如果准备好的语句的这种实现是安全的sql注入

*此安全问题的几乎所有注释都涉及PDO解决方案,其中在文档中注意到驱动程序阻止了sql注入.但如果一个简单的解决方案可能是pg_prepare,我现在会使用pg_prepare.*

感谢您提供最佳实践解决方案的重要信息.

编辑(标记解决方案后):
感谢非常有启发性的答案!

>我将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');
}

解决方法:

准备好的语句对sql注入是安全的,因为没有人可以在准备好之后更改查询计划.但是,如果您的语句已经被破坏,您仍然会遭受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");
}
?>

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...