用户名(和密码)中的Unicode?

时间:2011-01-20 03:02:24

标签: php mysql security unicode username

After reviewing this我意识到我还有一些关于这个主题的问题。

出于合法的安全目的,是否应该“遗漏”任何字符?这包括所有字符,例如括号,逗号,撇号和括号。

在这个主题上,我承认不明白为什么管理员似乎喜欢强制执行“你只能使用字母,数字和空格”规则。还有什么可能是安全漏洞或破坏我不知道的东西(即使是ASCII)?据我在编码期间看到的情况,绝对没有理由禁止任何角色使用用户名。

6 个答案:

答案 0 :(得分:4)

没有安全原因不使用某些字符。如果您正确处理所有输入,无论您是仅处理字母数字字符还是中文,都没有任何区别。

更容易处理alphnum用户名。您不需要考虑数据库中的排序规则的歧义,在URL中编码用户名以及类似的事情。但同样,如果你正确处理它,没有技术上的理由反对它。

出于实际原因,密码通常只是字母数字。例如,大多数密码输入不接受IME输入,因此几乎不可能拥有日语密码。但是,没有任何安全理由可以禁止使用非孤儿字符。相反,可用字母越大越好。

答案 1 :(得分:4)

如果您的应用程序在整个过程中正确处理Unicode输入,我当然会在用户名和密码中允许使用非ASCII字符,但需要注意几点:

  1. 如果您使用HTTP基本身份验证,则无法正确支持用户名和密码中的非ASCII字符,因为传递这些详细信息的过程涉及到编码到字节 - in-base64步骤,目前,浏览器不同意:

    • Safari使用ISO-8859-1,如果存在任何非8859-1字符则会中断;
    • Mozilla使用编码为UTF-16代码单元的每个字符的低字节(与这些字符的ISO-8859-1相同);
    • Opera和Chrome使用UTF-8
    • IE在其安装的系统上使用ANSI代码页,可以是任何东西,但不管是ISO-8859-1还是UTF-8。不符合编码的字符会被任意修改。
  2. 如果使用cookie,则必须确保以某种方式编码任何Unicode字符(例如URL编码),因为再次尝试发送非ASCII字符会在不同的浏览器中产生截然不同的结果。

  3.   

    “你只能使用字母,数字和空格”

    你得到空间吗?豪华!

答案 2 :(得分:2)

通常,这些字符可用于在程序中注入恶意代码。例如SQL injection(引号,破折号等),XSS/CSRF(引号,鱼括号等),甚至在代码中其他地方使用eval()时编程语言注入。

当您作为开发人员正确清理用户控制的输入/输出时,即通过HTTP请求进入的所有内容时,这些字符通常不会造成伤害;标题,参数和正文。例如。参数化查询或在SQL查询中内联它们时使用mysql_real_escape_string()以防止SQL注入,并在HTML中内联它们时使用htmlspecialchars()来阻止XSS。但我可以想象管理员不信任所有开发人员,所以他们添加了这些限制。

另见:

答案 3 :(得分:2)

我认为没有理由不允许在用户名中使用unicode。密码是不同的故事,因为当你在表单中键入密码时通常不会看到密码,只允许ASCII有意义以防止可能的混淆。

我认为使用电子邮件地址作为登录凭据是有意义的,而不是要求创建新的用户名。然后,用户可以使用任何unicode字符选择任何昵称,并在用户的帖子和评论旁边显示该昵称。

这不是它在Facebook上的表现吗?

答案 4 :(得分:1)

我认为大多数情况下,当事物(用户名或密码)被强制转换为ASCII时,这是因为有人担心更复杂的字符集会导致某些未知组件出现故障。这种恐惧是否合理取决于案例,但是在所有情况下尝试验证整个堆栈是否确实正确地执行Unicode可能很困难。它每天都在变好,但在某些地方你仍然可以发现Unicode的问题。

我个人保持我的用户名和密码都是ASCII,我甚至尽量不要使用太多的标点符号。一个原因是某些输入设备(如某些移动电话)使得某些更深奥的角色变得难以接受。另一个原因是我不止一次遇到过一个对密码内容没有限制的系统,但如果你真的使用了字母或数字以外的其他东西,那就搞砸了。

答案 5 :(得分:1)

如果程序的某些部分假设具有不同字节的字符串不同,则存在风险,但程序的其他部分将根据unicode语义比较字符串并认为它们是相同的。

例如,Mac OS X上的文件系统强制统一表示Unicode字符,因此有两个不同的文件名Ą('A with ogonek')和A + ̨(拉丁A后跟'合并ogonek')将引用同一个文件。

类似地,可以产生无效的 UTF-8字节序列,其中1字节码点被编码为多个字节(称为超长序列)。如果您在处理之前标准化或拒绝UTF-8输入,那么它将是安全的,但是例如如果您使用Unicode无知的编程语言和支持Unicode的数据库,这两个将看到不同的输入。

为避免这种情况:

  • 您应该尽早过滤UTF-8输入。拒绝无效/过长的序列。

  • 比较Unicode标记时,请始终将比较的两边转换为相同的Unicode标准格式。对于用户名,您可能希望NFKD减少可能的单应性攻击量。