【问题标题】:Allow only letters and digits in strings but without confusables只允许字符串中的字母和数字,但不能混淆
【发布时间】:2014-11-29 11:32:24
【问题描述】:

假设我希望用户名仅由字母和数字组成,而与语言无关。

我想我可以使用以下正则表达式部分来完成此操作

(?>\p{L}[\p{Mn}\p{Mc}]*) //match any letter, including those consisting of two code points

\p{Nd} //match any digit

现在我遇到的问题是,用户可能会通过使用与其他用户的用户名相同的用户名来伪装成其他用户(同形词攻击)。 admin vs admin 就是一个例子。

我想不可能使用正则表达式轻松排除既是字母又是易混淆的字符,但是在正则表达式的上下文之外呢?混淆物的 unicode id 是否位于我们可以过滤或类似的范围内?

【问题讨论】:

  • 有这个功能的库;他们在大表中收集同形异义词并将它们编译成一个正则表达式。
  • 有趣,我想我必须搜索它们。

标签: regex string unicode homoglyph


【解决方案1】:

易混淆...然后想到你在谈论西里尔字符。如果这是正确的,您可以轻松地将它们从您的 RegEx 中排除。考虑以下范围:

西里尔文:U+0400–U+04FF,256 个字符

西里尔文补充:U+0500–U+052F,48 个字符

Cyrillic Extended-A:U+2DE0–U+2DFF,32 个字符

Cyrillic Extended-B:U+A640–U+A69F,96 个字符

语音扩展:U+1D2B、U+1D78、2 个西里尔字符

然后:

/[^\x{0400}-\x{04FF}\x{0500}-\x{052F}\x{2DE0}-\x{2DFF}\x{A640}-\x{A69F}\x{1D2B}\x{1D78}]/u

或者简单地使用[^\p{Cyrillic}]

【讨论】:

  • 西里尔字符是唯一容易混淆的字符吗?我担心可能有比西里尔字母更容易混淆的字母。
  • @user764754 是的,西里尔字符是同形异义词攻击中最常用的字符。然而,通过这种方式,我排除了这个可爱集合中的所有角色,但正如维基百科所述 it contains 11 lowercase glyphs that are identical or nearly identical to Latin counterparts
  • “用户名仅由字母和数字组成,而与语言无关” 如果我理解得很好,用户应该能够使用他们的本机字符集进行注册。因此,盲目拒绝某些西里尔字符会任意阻止使用该字符集的真实用户名。
  • @revo 这当然很有帮助,但是当攻击者可以使用其他字符时,西里尔字符是使用最多的字符这一事实并不能保证安全。在 Sylvain Leroux:是的,但我认为在某些条件下允许混淆会导致极大的复杂性。
  • @user764754 这个话题本身是有争议的,但由于语言之间的大量比较,它并不实用。对我来说,如果我是你,我会以一种语言为基础(也许是英语?!)并尝试收集其字母的同形字符。通过这种方式,我确信人们可以拥有许多相同的用户名,但这并不重要,因为我所知道的只是我的基本语言,我确保它是安全的。
【解决方案2】:

Unicode 标准在http://www.unicode.org/Public/security/revision-02/confusables.txt 处包含一个易混淆字符列表

有些人认为此列表不完整,有些人认为此列表过于激进,但请查看它以了解一般解决问题的难度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    相关资源
    最近更新 更多