【问题标题】:preg_match username validation regex allows > and < despite those characters not being whitelistedpreg_match 用户名验证正则表达式允许 > 和 < 尽管这些字符未列入白名单
【发布时间】:2012-04-03 15:53:30
【问题描述】:

我有这个相对简单的用户名正则表达式

// Enforce that username has to be 3-100 characters, alphanumeric, and first character a letter.
// Possibility without begin/end characters and i: [a-z][a-z0-9@.+-_]{2,100}
// Allow for simple email usernames in the future...
return !!preg_match('#^[a-zA-Z][a-zA-Z0-9@.+-_]{2,100}$#', trim($username));

不幸的是,这允许这些 XSS-ready 测试字符串:

'angle<bracket',
'angle>bracket',
'html<script>inside',

我不知道为什么,因为它们已经被正则表达式明确禁止。

这是一个正在运行的测试用例:

http://ideone.com/od7dj

谁知道为什么尖括号被一个没有明确允许的正则表达式允许?我应该将其中一个字符 (.+-) 转义为文字吗?

【问题讨论】:

  • 使用明确的(bool) 演员而不是!! - 双重不是不好的做法,因为它的用途并不总是很明显。

标签: php regex preg-match


【解决方案1】:

+-_ 是你的问题。您需要对字符类中的- 进行转义或将其移动到类的末尾或开头。

例如:

/^[a-z][a-z0-9@.+_-]{2,100}\z/i

【讨论】:

    【解决方案2】:

    我想是因为这个:[+-_]

    您将包含 '+' 和 '_' 之间的所有字符,请尝试将顺序更改为 [+_-](将破折号放在末尾)或转义破折号。

    【讨论】:

    • 这确实解释了-为什么-这些字符会导致问题,因为它充当了一个范围,谢谢。将来,当我按字面意思使用破折号时,我会避开破折号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多