繁体   English   中英

避免使用Zend_Db类进行MySQL注入

[英]avoiding MySQL injections with the Zend_Db class

我目前使用Zend_Db来管理我的查询。 我已经编写了代码,可以执行如下所示的查询:

$handle->select()->from('user_id')
                   ->where('first_name=?', $id)
                   ->where('last_name=?', $lname)

假设Zend_Db会这样做,我没有清理输入就完成了这个。 Zend会这样做吗?

另一个问题:Zend_Db是否清理insert('table', $data)update查询?

谢谢。

我在Zend Framework中编写了很多用于数据库参数和引用的代码,而我是该项目的团队负责人(最高版本1.0)。

我试图在可能的情况下鼓励最佳实践,但我必须在易用性方面取得平衡。

请注意,您始终可以检查Zend_Db_Select对象的字符串值,以查看它是如何决定进行引用的。

print $select; // invokes __toString() method

您还可以使用Zend_Db_Profiler检查Zend_Db代表您运行的SQL。

$db->getProfiler()->setEnabled(true);
$db->update( ... );
print $db->getProfiler()->getLastQueryProfile()->getQuery(); 
print_r $db->getProfiler()->getLastQueryProfile()->getQueryParams(); 
$db->getProfiler()->setEnabled(false);

以下是您具体问题的一些答案:

  • Zend_Db_Select::where('last_name=?', $lname)

    适当引用值。 虽然“ ? ”看起来像参数占位符,但在此方法中,参数实际上是适当引用并进行插值的。 所以它不是一个真正的查询参数。 实际上,以下两个语句产生与上述用法完全相同的查询:

     $select->where( $db->quoteInto('last_name=?', $lname) ); $select->where( 'last_name=' . $db->quote($lname) ); 

    但是,如果传递的参数是Zend_Db_Expr类型的对象,则不会引用它。 您负责SQL注入风险,因为它是逐字插入的,以支持表达式值:

     $select->where('last_modified < ?', new Zend_Db_Expr('NOW()')) 

    该表达式中需要引用或分隔的任何其他部分是您的责任。 例如,如果将任何PHP变量插入到表达式中,则安全是您的责任。 如果列名是SQL关键字,则需要使用quoteIdentifier()分隔它们。 例:

     $select->where($db->quoteIdentifier('order').'=?', $myVariable) 
  • Zend_Db_Adapter_Abstract::insert( array('colname' => 'value') )

    表名称和列名称是分隔的,除非您关闭AUTO_QUOTE_IDENTIFIERS

    将值参数化为真实查询参数(未插入)。 除非该值是Zend_Db_Expr对象,在这种情况下,它是逐字插值的,因此您可以插入表达式或NULL或其他任何内容。

  • Zend_Db_Adapter_Abstract::update( array('colname' => 'value'), $where )

    表名称和列名称是分隔的,除非您关闭AUTO_QUOTE_IDENTIFIERS

    值是参数化的,除非它们是Zend_Db_Expr对象,如insert()方法。

    $where参数根本没有被过滤,所以你要对那个中的任何SQL注入风险负责。 您可以使用quoteInto()方法来帮助使引用更方便。

是。 http://framework.zend.com/manual/en/zend.db.select.html 别担心。 你持怀疑态度是正确的。

默认情况下,在SQL查询中使用值绑定时,如下所示:

where('first_name=?', $id);

Zend_Db使用适当的值引用来防止SQL注入。 虽然强烈建议(通过书籍,文章,手册和自我体验)清理/过滤用户输入。 Zend_Filter非常有帮助。

应该让你觉得安全的一点是? 在where子句中标记。 这些参数由数据库系统安全地替换为第二个参数。

当你需要它在其他地方(比如在连接中)或者你不确定它是否会被转义然后你总是可以使用$this->getAdapter()->quoteInto('type = ?',1);

过滤输入总是很好,因为它可能会在某个地方而不仅仅是数据库,并且您至少需要在某个级别的数据库中获得理智的数据。

  • Zend_Filter_Input在路上
  • 准备好的陈述(如果没有准备好,则为quoteInto)
  • 逃离过滤器(htmlentities等)。

有一点是,当值为NULL时,您可以获得无效的查询

$value = NULL;
$select->where('prop=?', $value);

结果:SQL错误

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM