WordPress PHP,为什么 LIKE 类型的查询需要esc_like方法?

WordPress PHP, why esc_like method is needed for LIKE type of query?

提问人:Erasus 提问时间:12/17/2022 更新时间:3/18/2023 访问量:390

问:

所以我有点困惑为什么在 WordPress 上有像 esc_like() 这样的方法: https://developer.wordpress.org/reference/classes/wpdb/esc_like/ 建议是 LIKE 将使用的参数必须用 esc_like() 进行转义以使其安全,如下所示:

$wild = '%';
$find = 'only 43% of planets';
$like = $wild . $wpdb->esc_like( $find ) . $wild;
$sql  = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like);

但是为什么:

$sql  = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like);

在这种情况下,正确准备 LIKE 参数还不够吗?我不明白使用esc_like可能会出错的地方,如果在没有这种esc_like方法的情况下使用,真的会导致漏洞吗?

据我所知,$wpdb->准备就足够了,但最近了解这一点我不确定。

所以主要的问题是,如果我在没有 $wpdb->esc_like() 方法的情况下使用它,它会带来非常严重的安全风险吗?

php wordpress sql 注入

评论

0赞 vee 12/17/2022
在该文档页面中,查看源代码。它只是在 、 、 中添加 C 斜杠。这意味着它将被转义为搜索关键字。%_\\43%
0赞 Your Common Sense 12/18/2022
恐怕你只是混淆了什么。您链接到的页面说的恰恰相反,“输出不是 SQL 安全的”(强调我的)。因此,此页面没有任何地方声称此功能可以使任何“安全”的东西。只是更方便和可预测。

答:

2赞 Bill Karwin 12/18/2022 #1

你说得对,为了防止SQL注入,你必须使用查询参数。

“转义”LIKE 字符串的目的与阻止 SQL 注入的目的不同。

和字符是 LIKE 表达式中的通配符。但是,如果您想从字面上匹配这些角色怎么办?%_

SQL 提供了一个解决方案:

https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html#operator_like

若要测试通配符的文本实例,请在其前面加上转义字符。

默认转义字符为 。\

评论

0赞 O. Jones 12/18/2022
先生们,请看我的回答。WordPress 的 SQL 驱动程序 API 奇怪地处理了这种转义。最好按照规定使用它,而不是为了这些 LIKE 常量而逃避自己,否则事情可能会破裂。
0赞 Bill Karwin 12/18/2022
好吧,我正在查看这里的文档和代码: developer.wordpress.org/reference/classes/wpdb/esc_like 我看到使用示例显示了将其与准备好的查询相结合,但我认为这只是为了显示应用它的正确顺序,如果您在准备好的查询中使用它。
1赞 O. Jones 12/18/2022 #2

WordPress 使用独特且文档不完整的方案进行处理。显示一些以这种方式准备的 SQL,你就会明白我的意思了——长 uniqueid 字符串出现,稍后在阶段被理顺。$wpdb->prepare()->execute()

->esc_like()是该计划的一部分。当然,其中很多都是为了预防注射。

评论

0赞 Your Common Sense 12/18/2022
我不同意。esc_like()与注射预防关系不大。只是一些意想不到的结果预防。
0赞 user2088350 3/18/2023 #3

如果该值是用户输入或从数据库或全局变量中获取$SERVER则必须对其进行转义。 我是这样用的:

$post_id = $wpdb->get_var(
                $wpdb->prepare(
                    "SELECT ID from {$wpdb->prefix}posts     WHERE post_name LIKE %s LIMIT 1", 
                    '%' . $wpdb->esc_like( $basename ) . '%'
                )
            );