“在序列化实例中具有 NULL 字节的文件名”是什么意思?
空字节是值为零的字节,即十六进制的 0x00。
存在与空字节相关的安全漏洞。这些发生是因为 C 使用空字节作为字符串终止符。其他语言(Java、PHP 等)没有字符串终止符;它们分别存储每个字符串的长度。
现在,考虑一个接受文件上传的 Java Web 应用程序。也许我们想让用户上传.jpg文件,但没有别的。事实上,如果用户可以上传.jsp文件,这将是一个严重的安全漏洞。
黑客可能会尝试上传hack.jsp<NUL>.jpg. 让我们想想这将如何处理。首先,Java 会查看文件名,看到它的结尾.jpg并允许上传。然后它调用用 C 编写的操作系统库。C 将<NUL>字符视为字符串终止符,因此将文件保存为hack.jsp.
许多语言通过明确禁止<NUL>文件名中的字节来解决此问题。我知道 Python 和 PHP 可以做到这一点。但是,如果您的语言不适合您,您必须自己做。更多信息 - OWASP:空字节注入
我不知道“序列化实例”与此有何关系,但我认为这让您对发生了什么有所了解。
每个字符都有一个由相应字符集规定的数值。因此,例如,通常Ais65和ais 97。但是如果数字是0,那么它就不是一个真正的字符,它是一个“空”;这基本上意味着不是一个字符。
在 C 和 C++ 中,此“空”字符用于表示字符串的结尾。所以“HELLO”是这样存储的:
H E L L O
72 69 76 76 79 00
最后00说“停在这里”。但并非所有框架都使用 C 字符串及其“空终止符”格式;事实上大多数都没有。相反,字符串的长度是预先存储的,实际内容可以包含任何内容,包括这些空字符——数值为 的字符0。
所以在这种情况下,如果名称包含这些空字符之一,大多数代码都不会介意;允许空字节。但是,当该名称出现在 FileUpload 代码中时,该null最终会引起一些混乱。一些代码认为名称以空字节结尾,而其他位认为空字节只是另一个字母。这种混淆,即两段代码对名称的实际含义不一致,会导致安全漏洞。