使用 Zend_Db 类避免 MySQL 注入
我目前使用 Zend_Db 来管理我的查询。 我已经编写了执行如下查询的代码:
$handle->select()->from('user_id')
->where('first_name=?', $id)
->where('last_name=?', $lname)
我在没有清理输入的情况下完成了此操作,假设 Zend_Db 会这样做。 Zend有这个功能吗?
另一个问题: Zend_Db 是否清理 insert('table', $data)
和 update
查询?
谢谢。
I currently use Zend_Db to manage my queries.
I've written already code that preforms queries like the one below:
$handle->select()->from('user_id')
->where('first_name=?', $id)
->where('last_name=?', $lname)
I've done this without sanitizing the input, assuming Zend_Db will. Does Zend do this?
Another question:
Does Zend_Db sanitize insert('table', $data)
and update
queries?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
当我担任该项目(直到版本 1.0)的团队负责人时,我在 Zend Framework 中编写了很多数据库参数和引用的代码。
我试图尽可能鼓励最佳实践,但我必须在易用性之间取得平衡。
请注意,您始终可以检查
Zend_Db_Select
对象的字符串值,以了解它如何决定进行引用。您还可以使用
Zend_Db_Profiler
来检查Zend_Db
代表您运行的 SQL。以下是针对您的具体问题的一些答案:
Zend_Db_Select::where('last_name=?', $lname)
值被适当引用。 尽管“
?
”看起来像参数占位符,但在此方法中,参数实际上被适当地引用并插入。 所以它不是真正的查询参数。 事实上,以下两条语句产生与上述用法完全相同的查询:但是,如果您传递的参数是
Zend_Db_Expr
类型的对象,则它不会被引用。 您需要承担 SQL 注入风险,因为它是逐字插入的,以支持表达式值:该表达式中需要引用或分隔的任何其他部分是您的责任。 例如,如果您将任何 PHP 变量插入到表达式中,安全性就是您的责任。 如果您的列名是 SQL 关键字,则需要使用
quoteIdentifier()
自行分隔它们。 示例: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()
方法来帮助使引用更加方便。I wrote a lot of the code for database parameters and quoting in Zend Framework while I was the team lead for the project (up to version 1.0).
I tried to encourage best practices where possible, but I had to strike a balance with ease of use.
Note that you can always examine the string value of a
Zend_Db_Select
object, to see how it has decided to do quoting.Also you can use the
Zend_Db_Profiler
to inspect the SQL that is run on your behalf byZend_Db
.Here are some answers to your specific questions:
Zend_Db_Select::where('last_name=?', $lname)
Values are quoted appropriately. Although the "
?
" looks like a parameter placeholder, in this method the argument is actually quoted appropriately and interpolated. So it's not a true query parameter. In fact, the following two statements produce exactly the same query as the above usage:However, if you pass a parameter that is an object of type
Zend_Db_Expr
, then it's not quoted. You're responsible for SQL injection risks, because it's interpolated verbatim, to support expression values:Any other part of that expression that needs to be quoted or delimited is your responsibility. E.g., if you interpolate any PHP variables into the expression, safety is your responsibility. If you have column names that are SQL keywords, you need to delimit them yourself with
quoteIdentifier()
. Example:Zend_Db_Adapter_Abstract::insert( array('colname' => 'value') )
Table name and column names are delimited, unless you turn off
AUTO_QUOTE_IDENTIFIERS
.Values are parameterized as true query parameters (not interpolated). Unless the value is a
Zend_Db_Expr
object, in which case it's interpolated verbatim, so you can insert expressions orNULL
or whatever.Zend_Db_Adapter_Abstract::update( array('colname' => 'value'), $where )
Table name and column names are delimited, unless you turn off
AUTO_QUOTE_IDENTIFIERS
.Values are parameterized, unless they are
Zend_Db_Expr
objects, as ininsert()
method.The
$where
argument is not filtered at all, so you're responsible for any SQL injection risks in that one. You can make use of thequoteInto()
method to help make quoting more convenient.是的。 请参阅 http://framework.zend.com/manual/en/zend .db.select.html 。 不用担心。 你的怀疑是对的。
Yes. See http://framework.zend.com/manual/en/zend.db.select.html . Don't worry. You're right to be skeptical.
默认情况下,当您在 SQL 查询中使用值绑定时,如下所示:
Zend_Db 使用适当的值引用来防止 SQL 注入。 尽管强烈建议(通过书籍、文章、手册和自身经验)清理/过滤用户输入。 Zend_Filter 非常有帮助。
by default when you use value binding in your SQL queries like this:
Zend_Db uses appropriate quoting of values to prevent SQL injection. although it is strongly recommended (by books, articles, manuals and self experience) to sanitize/filter user input. Zend_Filter can be very helpful.
应该让您感到安全的一点是? where 子句中的标记。 这些是参数,由数据库系统安全地替换为第二个参数。
The bit that should make you feel safe is the ? marks in the where clauses. These are parameters, which are safely replaced with the second argument by the database system.
当您在其他地方需要它(例如在 join 中)或者您不确定它是否会被转义时,您始终可以使用 $this->getAdapter()->quoteInto('type = ?',1);
When you need it somewhere else (like in join) or you are unsure if it will be escaped then you can always use
$this->getAdapter()->quoteInto('type = ?',1);
过滤输入总是好的,因为它很可能会进入数据库以外的其他地方,并且您至少希望数据库中的数据在某种程度上保持正常。
Zend_Filter_Input
在Filtering input is always good, because likely it'll be going somewhere other than just the DB, and you at least want sane data in your database at some level.
Zend_Filter_Input
on the way in关于这一点的一件事是,当值为 NULL 时,您可以实现无效查询
结果:SQL 错误
One thing about this, when value is NULL, you can achieve not valid query
Result: SQL error