首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pg_prepare()准备好的语句(而不是PDO)会阻止SQL注入吗?

pg_prepare()准备好的语句(而不是PDO)会阻止SQL注入吗?
EN

Stack Overflow用户
提问于 2012-08-10 07:54:59
回答 4查看 6.7K关注 0票数 4

PDO在目标系统中不受支持,我正在研究,尽管我在PostGres 8.2+上寻求使用PHP5.1.x来防止注入的解决方案。目前,没有切换到PDO的机会。

我目前的解决办法是准备准备好的声明:

代码语言:javascript
复制
// 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语句来创建与pg_prepare()一起使用的准备语句。(但是pg_prepare()更灵活,因为它不需要预先指定参数类型。)另外,尽管没有PHP函数来删除已准备好的语句,但语句可以用于此目的。

,但它不能说明,准备好的语句的实现是否安全,不受SQL-injection的影响。

*几乎所有这个安全问题的注释都提到PDO-解决方案,在文档中会注意到驱动程序阻止SQL注入。但是,如果一个简单的解决方案可能是pg_prepare,我现在就会使用pg_prepare。

感谢您提供的关于可能是最佳实践解决方案的重要信息。

编辑(标记为解决方案后):,谢谢您给出的非常有启发性的答案!

  • 我把Frank Heikens的解决方案标记为最佳答案,因为它解释了SQL注入中的一个要点。程序员可能会使用预先准备好的状态,但是SQL注入的不足可能仍然是错误的!
  • 除了Frank Heikens的回答外,hoppa还表明使用pg_ from /pg_query_params可以防止SQL注入。不过还是谢谢。
  • 现在将使用pg_query_params优化的代码(感谢MilenA.Radev)
  • pg_escape_string()作为替代,当涉及到它(感谢半个)

所有答案都是有帮助的:)

代码语言:javascript
复制
// 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');
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-08-10 08:25:22

准备好的语句在SQL注入中是安全的,因为在准备好查询计划之后,没有人能够更改它。但是,如果您的语句已经被破坏,那么您仍然会受到SQL注入的影响:

代码语言:javascript
复制
<?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");
}
?>
票数 6
EN

Stack Overflow用户

发布于 2012-08-10 08:00:54

准备好的语句被内置到MySQL (http://dev.mysql.com/doc/refman/5.6/en/sql-syntax-prepared-statements.html)中。注入预防机制也在MySQL中,请参阅前面链接的页面中的引用:

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

PHP库只是将它们的功能映射到MySQL函数(可能使用01/refman-5.0-en/c-api-prepared-statement-function-overview.html)。所以是的,pg_prepare也应该保护你的注射。

我刚刚注意到您在谈论PostgreSQL,对于PostgreSQL来说,这是一个内置的语言特征,而不是PHP库提供的东西。

票数 2
EN

Stack Overflow用户

发布于 2012-08-10 08:11:52

就我从文档中收集到的信息而言,它应该可以防止SQL注入。

一种更通用的方法是使用pg_query_params,因为它与准备查询无关。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11897546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档