DOM XSS的原理与防护

时间:2024-11-08 19:13:40

前言

首先这里为什么要讨论DOM XSS而不是比较常见的反射型XSS和存储型XSS,因为基于DOM XSS原理和利用场景,服务端过滤及客户端转义的防护手段并不能完全适用于DOM XSS。


DOM  XSS原理

与反射型XSS、存储型XSS的区别就在于xss代码并不需要服务器解析响应的直接参与,触发XSS靠的是浏览器端的DOM解析。

例如如下代码:

<script>
  ("a").innerHTML="yyyyyy";
</script>

如果yyyyyy内容是请求过来的参数,那么攻击者就可以通过构造请求的参数完成DOM XSS攻击。

其实DOM XSS的形成原因及其它的难防护性,与浏览器对DOM的渲染有很大关系。

JavaScript与HTML自解码机制

首先来看样例1,如下

<input type="button"  οnclick="('<img src=@ οnerrοr=alert(1) />')" />

当执行时,会弹出提示框,如下图


说明JavaScript执行之前,HTML形式的编码会自动解码。这样的编码形式有以下两种:

  1. 进制编码:&#xH;(十六进制格式)、&#D;(十进制格式),最后的分号(;)可以不要
  2. Html实体编码

样例2,如下

<script>
  ("a").innerHTML="<img src=@ οnerrοr=alert(1) />";
</script>

并没有弹出提示框,如下图:


这段HTML编码的内容在JavaScript执行之前并没有自动解码,因为用户输入的这段内容上下文环境是JavaScript,不是HTML(可以认为<script>标签里的内容和HTML环境毫无关系),此时用户输入的这段内容要遵守的是JavaScript法则,即JavaScript编码,具体有如下几种形式。

  • Unicode形式:\uH(十六进制)
  • 普通十六进制:\xH
  • 纯转义:\'、\"、\<、\>这样在特殊字符之前加\进行转义

通过以上两个例子,知道了HTML和JavaScript自动解码的差异,如果防御没有区分这样的场景,就会出现问题。

在HTML标签中,有些标签是不会解析的,例如:

<textarea>

<title>

<iframe>

<noscript>

<noframes>

<xmp>

<plaintext>.


防护方案

1.在输入点过滤敏感关键字

=encodeHTML([输出])