这个preg_replace有什么作用?(/[\xF0-\xF7].../)

What does this preg_replace do? (/[\xF0-\xF7].../)

提问人:user1796995 提问时间:12/1/2012 最后编辑:Sam Darkuser1796995 更新时间:11/17/2023 访问量:1116

问:

显然$data字符串,我们正在删除满足 reg 表达式的字符,但是 /[\xF0-\xF7].../ 指定了哪些字符?

 preg_replace('/[\xF0-\xF7].../', '', $data)

另外,这些角色被替换的意义是什么?

编辑赏金:具体来说,这是为了防止什么漏洞的发生?这些数据后来被用于 mysql 查询(非 pdo),所以我推测这些字符可能涉及某种注入攻击?或不?我正在尝试在我正在阅读的脚本中理解这行代码背后的逻辑。

php mysql 正则表达式 utf-8 sql 注入

评论

2赞 NullUserException 12/1/2012
匹配从 到 的一系列字符xF0xF7
7赞 NullUserException 12/1/2012
ð ñ ò ó ô õ ö ÷
2赞 user1796995 12/1/2012
我的意思是,你为什么要逃避这些角色?它们不安全吗?
1赞 Sammitch 12/1/2012
@user1796995 它们很难输入,如果输入可能会被错误地解释。使用转义符可确保 PHP 获得所需的确切字符。
2赞 HamZa 1/14/2014
@user1796995 它根本没有逃脱,如果我问你,你会怎么回答?这很有可能是可能的。无论如何,有一些我们永远无法想象的极端情况,请看这个答案。最后,我真的不明白你的意思。如果你想提高安全性,那么只需正确使用准备好的语句。仅仅删除几个字符并不能保证任何事情。Would removing some accented letters prevent some exploits ?

答:

20赞 Sam Dark 1/14/2014 #1

它从 unicode 字符串中删除 4 字节序列。在这些中,第一个字节是 always,三个点是 3 个字节的其余部分。[\xF0-\xF7]

根据 http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html

名为 utf8 的字符集每个字符最多使用 3 个字节,并且仅包含 BMP 字符。

选择了 utf8 编码的 MySQL 可能会在序列出现时截断文本,如果未设置错误报告,它可能会静默执行,而不是抛出类似 .strict_trans_tablesSQLSTATE[HY000]: General error: 1366 Incorrect string value:

有关进一步参考,请参阅以下内容:

潜在的截断可导致漏洞利用。

例如,有一个用户名为 的网站。网站允许任何人注册。使用截断的字符串,人们可能能够插入另一个具有不同电子邮件的字符串,绕过唯一检查。然后暂停帐户并尝试使用还原过程。它将发出类似 and 的查询,因为原始管理员是第一个记录,攻击者将恢复他的密码。adminadminSELECT * FROM users WHERE name = 'admin'

评论

1赞 user1796995 1/14/2014
最后。一个非讽刺性的答案,一个对我有帮助的答案。谢谢你,你是个天才!
1赞 user1796995 1/21/2014
接受的答案 + 奖励赏金。谢谢。
1赞 Phil Perry 1/14/2014 #2

它匹配 8 个字节值之一,加上后面的任意 3 个字符,并删除 4 个字符的块。你说你已经知道了这么多。不幸的是,如果没有更多的上下文,我们无法告诉您为什么这些特定的 8 个字节很重要。就其本身而言,它们是无害的,无论它们代表什么字符字形(字符编码)。我最好的猜测是,在应用程序中,这 8 个字符作为某种标记具有一定的意义。0xF0是 11110xxx,即 32 位(4 字节)UTF-8 字符的第一个字节,所以也许是删除所有 32 位 UTF-8 字符?16 位和 24 位字符(110xxxxx 和 1110xxxx 第一个字节)是否具有类似的处理方式?

评论

0赞 user1796995 1/14/2014
看看山姆·达克的回答。您正在按照相同的方式删除所有 32 位 UTF-8 字符。我认为他已经做到了。
0赞 Phil Perry 1/14/2014
是的,我最终在他发布后 13 秒发布。我不知道MySQL截断了32位字符(显然,不是更短的字符)。当然,这种用法取决于 PHP 是否将 32 位 UTF-8 字符实际视为 4 个单独的字节(或者至少允许此类访问)。
0赞 Manolo 1/21/2014 #3

preg_replace('/[\xF0-\xF7].../', '', $data)取代:

(xF0 到 xF7) + 接下来的三个字符和一个空字符串(+ 符号表示串联,而不是加法)

0赞 Erin 11/17/2023 #4

从字符串中删除表情符号是旧代码。