一般来说,我会使用以下内容删除所有非英语字符:
$file = filter_var($file, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH );
但是,我厌倦了不提供对其他语言的用户输入的支持,这些输入可能采用上传文件的形式(文件名可能是西里尔语或中文,或阿拉伯语等)或表单字段,甚至来自所见即所得。
与此相关的数据清理示例采用两种形式之一
这种做法的问题是,你最终会得到一个破碎的框架,它假装它支持多种语言,但实际上除了可能用他们的语言向他们显示标签或内容之外,它实际上并不支持。
有许多攻击利用 unicode/utf-8/utf-16/etc 支持传递空字节等,因此很明显,不清理数据不是一个选项。
有没有办法从任意命令中清理变量,同时维护这些其他语言的完整字母/字符,但剥离(以通用方式)所有可能的不可打印字符,其中包含空值的字符char 和其他此类漏洞,同时保持用户输入的实际字符的完整性?上面的命令是完美的,并且完全按照应有的方式执行所有操作,但是如果有一种方法可以扩展它以允许支持所有语言,那就太酷了。
空字节不是(!)UTF-8,因此假设您在内部使用UTF-8,您需要做的就是验证传递的变量是否是UTF-8。例如,无需支持 UTF-16,因为您作为相应 API 或表单的作者定义了正确的编码,并且您可以将自己限制为 UTF-8。此外,“unicode”也不是您需要支持的编码,仅仅因为它不是一种编码。相反,Unicode 是一种标准,UTF 编码是其中的一部分。
现在,回到 PHP,您要查找的函数是 mb_check_encoding()。错误处理很简单,如果任何参数未通过该测试,您将回复“错误请求”响应。无需尝试猜测用户可能想要什么。
虽然问题没有具体询问这一点,但这里有一些示例以及如何在输入时处理它们:
../
):接受。../
):拒绝 400。شعار.jpg
、标志.png
或 логотип.png
:接受。foo <0> bar.jpg
:接受。abc
:拒绝 400。1234
:接受。以下是如何处理不同输出的方法:
شعار.jpg
、标志.png
或 логотип.png
:如果 HTML 编码为 UTF-8,则使用逐字记录,使用默认 ISO8859-1 时替换为 HTML 实体。شعار.jpg
、标志.png
或 логотип.png
:逐字使用,假设文件系统的编码为 UTF-8。شعار.jpg
、标志.png
或 логотип.png
:可能只是引用,取决于驱动程序、数据库、表等。请参阅手册。foo <0> bar.jpg
:转义为“foo <0> bar.jpeg”。也许使用“ ”作为空格。foo <0> bar.jpg
:用反斜杠引用或转义“”、“<" and ">”。foo <0> bar.jpg
:只需引用即可。abc
:不可能发生,他们之前被拒绝过。1234
:逐字使用。1234
:逐字使用(不确定)。1234
:逐字使用。一般程序应该是:
转义不是一个定义的过程,而是一系列过程。实际使用的转义算法取决于目标上下文。除了您所写的之外(“转义也会弄乱名称”),实际情况应该相反!基本上,它确保 XML 中包含小于号的字符串仍然是包含小于号的字符串,并且不会变成格式错误的 XML 片段。为了实现这一点,转义会转换字符串,以防止任何通常不被解释为文本的字符获得其正常解释,例如 shell 中的空格字符。