2017-08-30 28 views
0

在我的网站中,来自用户输入的任何html标记都被htmlspecialchars转义,然后我使用PHP json_encode发送html标记+转义用户内容作为JSON变量,这将转义所有“as \”,只有我放入因为用户输入已经被转义了。将JSON格式的HTML编码为HEX是必要的吗?

这工作得很好,我没有问题,我没有看到如何XSS攻击是可能的,我试过了。

但我看到Twitter和facebook将HEX所有的html标签编码,所以如果我要做同样的事情,我会添加选项JSON_HEX_TAG JSON_HEX_AMP JSON_HEX_APOS JSON_HEX_QUOTjson_encode()

那么,为什么Twitter和Facebook这样做,为什么我应该?我无法创建安全错误。

+0

'在旧浏览器上'... erm,Edge是**不是** onlder浏览器 –

+0

@Jaromanda我的意思是它适用于我测试过的所有浏览器IE9 + Edge Firefox Chrome Opera。我只是说好奇,如果你看看JSON文件,那么如果你输入开发者工具并在网络选项卡上搜索,那么浏览器不会很好地着色“变成\”的变量。它在Edge上完美地工作,所以我只是作为一个假设说,也许着色引擎没有更新,它的工作原理和旧的浏览器会读取JSON文件一样,只是猜测。 – Vixxs

+0

所以,你的问题不是关于代码的问题,而是关于开发者工具控制台漂亮打印? –

回答

0

从XSS的角度来看,您的策略听起来不错。十六进制编码可能支持其他语言/字符集?

+0

这个(多字节Unicode)在PHP 5.4.0之后默认完成,所以我也是这么做的。他们编码HTML标签,因此:< >&“'作为十六进制,默认的'json_encode'只能转义为”as“,它不会对HTML标签进行编码 – Vixxs

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> 

,它将输出“一个月的时间”,只要你想。

随着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> 

,它会输出 “一个月&#039;时间”,这已损坏的数据。这是因为它是HTML编码的,但没有直接插入到HTML上下文中。

如果要设置innerHTML属性或类似属性,尽管要阻止基于DOM的XSS,但应使用HTML编码,但这可以使用JavaScript而不是PHP来完成。