如何正确地为HTML属性上下文编码不可信数据?例如:
<input type="hidden" value="<?php echo $data; ?>" />
我通常使用
htmlentities()
或者 htmlspecialchars()
来实现这一功能:<input type="hidden" value="<?php echo htmlentities($data); ?>" />
然而,最近我遇到了一个问题,当我需要传递的数据是一个需要交给JavaScript更改页面位置的URL时,这个方法会破坏我的应用程序。
<input id="foo" type="hidden" value="foo?bar=1&baz=2" />
<script>
// ...
window.location = document.getElementById('foo').value;
// ...
</script>
在这种情况下,
foo
是一个C程序,它不会理解URL中的编码字符并导致段错误。我可以在JavaScript中简单地获取值并执行类似于
value.replace('&', '&')
的操作,但那看起来有些笨拙,而且只适用于“&”符号。因此,我的问题是:是否有更好的方法来处理注入HTML属性的数据的编码或解码?
我已经阅读了所有的OWASP XSS Prevention Cheatsheet,它让我感觉只要小心引用我的属性,那么我需要编码的唯一字符就是引号本身(
"
)-在这种情况下,我可以使用类似于str_replace('"', '"', ...)
的东西,但我不确定自己是否正确理解了它。
urlencode()
用于编码URL的参数,而不是整个URL,并且不会为HTML属性上下文编码。手册中甚至有一节讲到了这一点 - “将其保留为&,但只需使用htmlentities()或htmlspecialchars()对您的URL进行编码即可”。 - FtDRbwLXw6window.location = document.getElementById('foo');
是正确的吗?我认为应该改为window.location = document.getElementById('foo').value;
,并且它会重定向到正确的页面(foo?bar=1&baz=2)。 - Okan Kocyigitfoo?bar=1&baz=2
。PHP 能够理解这一点,但foo
不是 PHP 脚本,除非 URL 像foo?bar=1&baz=2
,否则它会崩溃。 - FtDRbwLXw6value
是foo?bar=1&baz=2
,如此处所示(http://jsfiddle.net/Zqkn3/)。根据你发布的脚本,它不会重定向到`foo?bar=1&baz=2`,而是重定向到`foo?bar=1&baz=2`。 - lanzz