gpt4 book ai didi

doctrine - 如何使用 Doctrine 转义 LIKE %$var% ?

转载 作者:行者123 更新时间:2023-12-02 13:39:56 24 4
gpt4 key购买 nike

我正在进行 Doctrine 查询,并且必须在 where 子句中进行通配符匹配。我应该如何转义要插入的变量?

我想要得到的查询:

SELECT u.* FROM User as u WHERE name LIKE %var%

到目前为止的 php 代码:

   $query = Doctrine_Query::create()
->from('User u')
->where();

where 子句中应该包含什么?我要匹配的变量是 $name

最佳答案

没有人正确回答你的问题,所以我会尝试一下。

->where('u.name LIKE ?', array("%$name%"));
->where('u.username LIKE ?', '%'.$username.'%')

这些都不安全。让我解释一下几个场景。

场景 1

假设您想让用户搜索匹配的用户名,但您永远不想列出所有用户名。也许您不希望有人轻易窃取您的一百万个用户名列表。在这段代码之前的某个地方,您做了类似的事情:

if (strlen(trim($name)) < 5) throw Boogey_Monster_Exception();

您认为这会阻止某人将该字段留空并下拉所有用户名的列表...但实际上用户可以提交“_____”或“%%%%%”或类似的内容来获取列表所有用户名,而不仅仅是匹配 5 个或更多已知字符。

我亲眼目睹过在几个大型公共(public)网站上使用这种形式的攻击。<​​/p>

场景 2

您的网站拥有大量用户和大量用户数据。您的用户表中有 10,000,000 行。您希望网站用户能够通过搜索已知前缀来查找其他用户的用户名。

因此,您编写了一些像这样的代码,对上面的示例稍加修改,只在搜索字符串后面有一个通配符。

->where('u.name LIKE ?', array("$name%"));

如果您在 u.name 上有索引,则此 LIKE 查询将使用该索引。因此,如果用户提交 $name="john",那么此查询将有效匹配 johndoe、johnwayne、johnwaynegacy 等用户。

但是,如果用户提交 $name="%john",则此查询不再使用索引,现在需要全表扫描。在非常大的数据库上,这可能是一个非常慢的查询。

关于 SQLi 的 MySQL 手册提到了同样的事情(第 78-79 页),我在 google 上搜索了一些查询性能缓慢的示例,并找到了一个链接。

这听起来可能没什么大不了的,但对于 RDBMS 支持的站点来说,RDBMS 通常是一个重要的瓶颈,并且大部分性能工程都是围绕减少 RDBMS 上的争用展开的。如果您有少数用户发起攻击,占用数据库句柄 60 秒以上,并且您有一小部分数据库句柄,您可以看到它如何快速扩展以独占所有数据库句柄并阻止合法用户能够得到一个。

链接

http://dev.mysql.com/tech-resources/articles/guide-to-php-security-ch3.pdf

http://forums.mysql.com/read.php?24,13397,13397

解决方案

无论如何,更好的解决方案(如上面链接的MySQL手册和评论者@Maxence所提到的,是使用addcslashes()):

$username = addcslashes("%something_", "%_");

请注意,由于这里的sql示例使用准备好的语句,它们完全不受sql注入(inject)的影响,因此没有必要也不可取地使用mysql_real_escape_string();它执行的转义只是为了防止 sql 注入(inject)。我们试图防止的是通配符注入(inject),这需要一个转义两个 sql 通配符“%”和“_”的函数。

关于doctrine - 如何使用 Doctrine 转义 LIKE %$var% ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2843009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com