如何在保持所有非拉丁字母支持的同时清理字符串

问题描述 投票:0回答:1

一般来说,我会使用以下内容删除所有非英语字符:

$file = filter_var($file, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH );

但是,我厌倦了不提供对其他语言的用户输入的支持,这些输入可能采用上传文件的形式(文件名可能是西里尔语或中文,或阿拉伯语等)或表单字段,甚至来自所见即所得。

与此相关的数据清理示例采用两种形式之一

  • 那些删除所有非英语字符的
  • 将所有非英语字符转换为英语字母替代品。

这种做法的问题是,你最终会得到一个破碎的框架,它假装它支持多种语言,但实际上除了可能用他们的语言向他们显示标签或内容之外,它实际上并不支持。

有许多攻击利用 unicode/utf-8/utf-16/etc 支持传递空字节等,因此很明显,不清理数据不是一个选项。

有没有办法从任意命令中清理变量,同时维护这些其他语言的完整字母/字符,但剥离(以通用方式)所有可能的不可打印字符,其中包含空值的字符char 和其他此类漏洞,同时保持用户输入的实际字符的完整性?上面的命令是完美的,并且完全按照应有的方式执行所有操作,但是如果有一种方法可以扩展它以允许支持所有语言,那就太酷了。

php sanitization
1个回答
1
投票

空字节不是(!)UTF-8,因此假设您在内部使用UTF-8,您需要做的就是验证传递的变量是否是UTF-8。例如,无需支持 UTF-16,因为您作为相应 API 或表单的作者定义了正确的编码,并且您可以将自己限制为 UTF-8。此外,“unicode”也不是您需要支持的编码,仅仅因为它不是一种编码。相反,Unicode 是一种标准,UTF 编码是其中的一部分。

现在,回到 PHP,您要查找的函数是 mb_check_encoding()。错误处理很简单,如果任何参数未通过该测试,您将回复“错误请求”响应。无需尝试猜测用户可能想要什么。

虽然问题没有具体询问这一点,但这里有一些示例以及如何在输入时处理它们:

  • 非 UTF-8 字节:拒绝 400(“错误请求”)。
  • 包含路径元素的字符串(如
    ../
    ):接受。
  • 文件名(不是文件路径)包含路径元素(如
    ../
    ):拒绝 400。
  • 文件名
    شعار.jpg
    标志.png
    логотип.png
    :接受。
  • 文件名
    foo <0> bar.jpg
    :接受。
  • 数字
    abc
    :拒绝 400。
  • 数字
    1234
    :接受。

以下是如何处理不同输出的方法:

  • 非 UTF-8 字节:不可能发生,它们之前被拒绝了。
  • 文件名包含路径元素:不可能发生,它们之前被拒绝了。
  • HTML 中的
  • 文件名
    شعار.jpg
    标志.png
    логотип.png
    :如果 HTML 编码为 UTF-8,则使用逐字记录,使用默认 ISO8859-1 时替换为 HTML 实体。
  • Bash 中的
  • 文件名
    شعار.jpg
    标志.png
    логотип.png
    :逐字使用,假设文件系统的编码为 UTF-8。
  • SQL 中的
  • 文件名
    شعار.jpg
    标志.png
    логотип.png
    :可能只是引用,取决于驱动程序、数据库、表等。请参阅手册。
  • HTML 中的
  • 文件名
    foo <0> bar.jpg
    :转义为“foo <0> bar.jpeg”。也许使用“ ”作为空格。
  • Bash 中的
  • 文件名
    foo <0> bar.jpg
    :用反斜杠引用或转义“”、“<" and ">”。
  • SQL 中的
  • 文件名
    foo <0> bar.jpg
    :只需引用即可。
  • 数字
    abc
    :不可能发生,他们之前被拒绝过。
  • HTML 中的
  • 数字
    1234
    :逐字使用。
  • Bash 中的
  • number
    1234
    :逐字使用(不确定)。
  • SQL 中的
  • 数字
    1234
    :逐字使用。

一般程序应该是:

  • 定义您的内部类型(字符串、文件名、数字)并拒绝任何不匹配的内容。这些类型创建约束(文件名不包括路径元素)并提供保证(文件名可以附加到目录以形成该目录内的文件名)。
  • 使用 HTML 模板库(我想到了 Moustache)。
  • 使用 SQL 的 DB 包装器库(PDO、Propel、Doctrine)。
  • 转义 shell 参数。我不知道该走哪条路,但我相信你会找到正确的方法。

转义不是一个定义的过程,而是一系列过程。实际使用的转义算法取决于目标上下文。除了您所写的之外(“转义也会弄乱名称”),实际情况应该相反!基本上,它确保 XML 中包含小于号的字符串仍然是包含小于号的字符串,并且不会变成格式错误的 XML 片段。为了实现这一点,转义会转换字符串,以防止任何通常不被解释为文本的字符获得其正常解释,例如 shell 中的空格字符。

© www.soinside.com 2019 - 2024. All rights reserved.