在我的网站中,来自用户输入的任何html标记都被htmlspecialchars
转义,然后我使用PHP json_encode
将html标记+转义的用户内容作为JSON变量发送,这样就可以“转义为” “,只有我放在html中的那些,因为用户输入已经被转义。
这很好用,我没有问题,我看不出XSS攻击怎么可能,我试过了。
但是我看到Twitter和facebook编码为HEX所有html标签,所以如果我这样做,我会将选项JSON_HEX_TAG JSON_HEX_AMP JSON_HEX_APOS JSON_HEX_QUOT
添加到json_encode()
。
那么为什么twitter和facebook这样做以及为什么我应该这样做?我无法创建安全错误。
答案 0 :(得分:0)
从XSS的角度来看,您的策略听起来不错。十六进制编码可能支持其他语言/字符集?
答案 1 :(得分:0)
通常,您需要转义括号和引号,因为它们可以逃脱周围的html上下文。 json_encode
本身仅在您输出到' .js'文件周围没有任何HTML。
这两种方法都可以阻止XSS,但不同之处在于它们会产生不同的输出。 htmlspecialchars
转换'<'到'& lt;' (一个html实体)和十六进制编码转换'<'到' \ u003C' (JavaScript字符串文字转义序列)。如果您要将数据发送到JavaScript变量,那么您希望使用JavaScript来确保数据的完整性。
假设您要发送消息"一个月的时间"到JavaScript。
使用十六进制编码,您可以写:
<script>
var input = <?php
$input = "One month's time";
$input = json_encode($input, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
echo $input;
?>;
console.log(input);
</script>
它会输出&#34;一个月的时间&#34;,如你所愿。
使用htmlspecialchars
,您可以写:
<script>
var input = <?php
$input = "One month's time";
$input = htmlspecialchars($input, ENT_QUOTES, "utf-8");
$input = json_encode($input);
echo $input;
?>;
console.log(input);
</script>
它将输出&#34;一个月&#039;时间&#34;,它已损坏数据。这是因为它的HTML编码但未直接插入HTML上下文。
如果要设置innerHTML属性或类似属性,则应使用HTML编码,但要防止基于DOM的XSS,但这可以使用JavaScript而不是PHP来完成。