在用户提交的数据中保留未转换的&符号是否存在安全风险?

时间:2012-06-14 05:31:41

标签: html string security validation escaping

在显示用户生成/提交的信息时,是否存在逃避其他特殊字符但未触及&符号的安全风险?我想让我的用户自由输入html实体,十六进制和十进制特殊字符,而不会给我的清洁剂增加不必要的复杂性。

2 个答案:

答案 0 :(得分:5)

tldr; 如果正确编码 保留&符号(或其他“特殊字符”)不是安全问题。也就是说,输出/使用非常重要,而不是输入

这一切都取决于最终如何使用数据。例如,对于任意输入,执行<input value="<? echo $input ?>" /> 未正确编码

现在&通常比其他一些字符(例如'"<>)更不是“问题”,但可能在某些情况下会导致一些工件(包括错误和未定义的行为),或者可能用于向URL添加额外的查询参数

  • ..但如果在输出时未按适当的方式对网址进行编码,那么未正确编码 1
  • ..当然,如果&逐字写入XML / HTML流,那么未正确编码 2
  • ..如果程序将原始& [从用户输入]传递给“shell string-execute”,那么[很可能] 未正确编码 3
  • ..一切都归结为使用。

我倾向于不改变输入,除了使其符合业务规则 - 这包括上述情况! (但根本不接受&符号可能是完全有效的商业规则。)

在适当的时间正确转义(或者更好的是,不需要[手动]转义的方法)可以完成剩下的工作并确保通过良好的用法编码,琐碎减轻了攻击或意外失误。

事实上,我认为这种“输入清理”表明对其他地方使用的方法/代码缺乏信任,并且可能导致更多问题需要撤消< / em>“消毒”。魔术引用任何人?


1 这是用户输入中的&实际上可以引起注入形式的情况。想象一下:format("http://site/view={0}", user_input),其中user_input包含1&buy=1。结果将是"http://site/view=1&buy=1"。正确的方法是URI-encode (aka Percent encode)该值,这将导致"http://site/view=1%26buy%3D1"。 (请注意,在正确编码的情况下只有一个查询参数。如果意图是允许“原始”输入通过,则仔细定义/分析允许的规则并查看以下段落。)

2 虽然“裸”&在HTML流中有效,但用户输入不应被视为“有效的HTML”。也就是说,无论是针对XML还是HTML,都应该使用正确的输出/呈现转义机制。 (转义机制可能选择不对“裸”&进行编码,但这是次要问题。lazy programmer将继续使用相同的转义技术适用的输出,以获得一致,可靠和安全的输出。)

3 使用exec-form接受参数列表,而不是使用shell-execute来获取必须解析的单个参数字符串。后者[通常]防止产生shell和相关的shell-hacks。当然,永远不要让用户手动指定可执行文件..

答案 1 :(得分:4)

这一切都取决于数据的上下文。

在HTML中,通过字符引用表示普通&的主要原因是avoid ambiguity,因为&也是此类字符引用的开头。这种歧义的一个流行示例是普通的&作为HTML属性中URL参数的一部分,如下所示:

<a href="/?lang=en&sect=foobar">

此处&未使用相应的字符引用进行适当编码,因此解析器将其视为字符引用的开头。由于 sect known entity in HTML,代表部分字符 §,因此该属性值实际上被解释为/?lang=en§=foobar

因此,保留普通&并不像HTML中的其他特殊字符那样存在实际威胁,因为它们可以更改数据的上下文:

  • 标记分隔符<>可以开始或结束标记声明,
  • 属性值分隔符"'可以开始或结束属性值声明。

为安全起见,您应使用htmlspecialchars并将 double_encode 参数设置为false,以避免对现有字符引用进行双重编码:

var_dump(htmlspecialchars('<"&amp;\'>', ENT_QUOTES, 'UTF-8', false) === '&lt;&quot;&amp;&#039;&gt;'); // bool(true)