本文为翻译版本,原文请查看 https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet

介绍

谈到XSS攻击,有三种公认的形式,Stored、 Reflected 和 DOM Based XSS。

XSS Prevention Cheatsheet可以有效地解决 Stored、 Reflected XSS攻击, 本检查单解决了 DOM Based XSS攻击,是 XSS Prevention Cheatsheet 的延伸。

为了理解DOM Based XSS攻击, 你需要理解Reflected和Stored XSS攻击与DOM Based XS的根本区别。

Reflected and Stored XSS是服务器端代码执行产生的问题,DOM based XSS是浏览器端代码执行产生的问题。

所有的代码都来源于服务器, 这意味着应用拥有者有责任保证应用免受XSS攻击,不管攻击是哪种类型XSS攻击。

当浏览器渲染HTML和其他关联内容,例如 CSS JS etc, 对于每种不同的上下文使用不同的规则进行渲染。

HTML解析器负责数据如何被显示并在页面上如何布局,并进一步分解为标准的环境,例如 HTML HTML属性 URL 和 CSS。JavaScript or VBScript解析器负责解析和执行脚本代码,每种解析器有不同的语法,这使得创建统一的预防漏洞的规则变得困难。复杂点在于混合了不同的意义和每种子环境(HTML, HTML attribute, URL, and CSS)对转码的处理方法。

本文将HTML, HTML attribute, URL, and CSS环境定义为子环境,因为每种环境都可以被JS环境访问和执行。

在JS代码中,主环境是JS,但是通过右标签(right tags)和环境关闭字符, 攻击者可以攻击其他四种环境,使用相同意义的JS DOM方法。

下面就是一个漏洞例子,发生在JS环境,由于HTML子环境被攻击:

<script>
var x = ‘<%= taintedVar %>’;
var d = document.createElement(‘div’);
d.innerHTML = x;
document.body.appendChild(d);
</script>

下面让我们按个查看下各个子环境。

规则#1 在脚本中将不可信数据插入到HTML前,先执行HTML转义、然后执行JS转义

存在几种方法和属性可以在JS中直接渲染HTML环境,如果这些方法和属性遇到了不可信的数据,那么XSS漏洞就发生了。

例如

-- 属性

element.innerHTML = “<HTML> Tags and markup”;
element.outerHTML = “<HTML> Tags and markup”;

--方法

document.write(“<HTML> Tags and markup”);
document.writeln(“<HTML> Tags and markup”);

指导方针

为了保证动态更新DOM中的HTML是安全的, 我们推荐对不可信数据进行

a) HTML编码

b)JS编码

如下面这些例子所示

element.innerHTML = “<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”;
element.outerHTML = “<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”;
document.write(“<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”);
document.writeln(“<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”);

注意: Encoder.encodeForHTML() and Encoder.encodeForJS() 仅仅是名字上的编码器,其中内部的实现在本文后面描述。

规则#2 在脚本中将不可信数据插入到HTML属性前,先执行JS转义

对于不执行代码的属性,即非event handler, CSS, and URL属性,只需要在JS中对属性值做JS转义。

var x = document.createElement(“input”);
x.setAttribute(“name”, “company_name”);
x.setAttribute(“value”, ‘<%=Encoder.encodeForJS(companyName)%>’);
var form1 = document.forms[0];
form1.appendChild(x);

同时,下面的例子指出,如果添加HTML转码是不对的,如果值被设置为“Johnson & Johnson”, 并且经过HTML转码,则结果为 “Johnson &amp; Johnson”。说明,通过DOM属性接口修改DOM,是不应用HTML解析规则的。

var x = document.createElement(“input”);
x.setAttribute(“name”, “company_name”);
// In the following line of code, companyName represents untrusted user input
// The Encoder.encodeForHTMLAttr() is unnecessary and causes double-encoding
x.setAttribute(“value”, ‘<%=Encoder.encodeForJS(Encoder.encodeForHTMLAttr(companyName))%>’);
var form1 = document.forms[0];
form1.appendChild(x);

规则#3 将不可信数据插入到事件处理句柄 和 JS 代码中,一定要小心

放动态数据到JS代码中是特别危险的,因为JS编码有不同的语义,相比较其它环境的编码。

在很多例子中,JS转码并不能阻止代码的执行。因此,首要的推荐是不要将不可信数据插入JS代码中。下面的代码演示了即使转义仍有风险的情况:

var x = document.createElement("a");
x.href="#”;
// In the line of code below, the encoded data on the right (the second argument to setAttribute)
// is an example of untrusted data that was properly JavaScript encoded but still executes.
x.setAttribute("onclick", "\u0061\u006c\u0065\u0072\u0074\u0028\u0032\u0032\u0029");
var y = document.createTextNode("Click To Test");
x.appendChild(y);
document.body.appendChild(x);

这是因为这些方法都将JS字符串,当做JS代码,并进行执行。具有相同风险的其他方法 (setTimeout, setInterval, new Function, etc.)。

规则#4 将不可信数据插入到CSS属性前先执行JS转义

暂无研究,待添加。

规则#5 将不可信数据插入到URL属性前,先执行URL转义,后执行JS转义

暂无研究,待添加。

利用JS开发安全应用指导方针

DOM based XSS及其难于根治, 由于其攻击面非常广,且跨浏览器的标准化。下面尝试给出指南,以帮助开发者开发JS应用的时候, 减少XSS漏洞。

1、 不可信的数据应该做为只显示的文本,不应该作为 JS代码或者标签被执行。

2、 对不可信数据总是采用JS转义,并添加引号的方法,让其出现在JS代码中。

var x = “<%=encodedJavaScriptData%>”;

3、 使用 document.createElement(“…”), element.setAttribute(“…”,”value”), element.appendChild(…), etc. 去创建动态接口。 其中, setAttribute 也不是特别安全, 对于一些将值作为JS代码的属性, 还是有安全风险, 例如onclick or onblur, 其他安全属性包括 align, alink, alt, bgcolor, border, cellpadding, cellspacing, class, color, cols, colspan, coords, dir, face, height, hspace, ismap, lang, marginheight, marginwidth, multiple, nohref, noresize, noshade, nowrap, ref, rel, rev, rows, rowspan, scrolling, shape, span, summary, tabindex, title, usemap, valign, value, vlink, vspace, width

4、 避免使用HTML渲染方法

  1. element.innerHTML = “…”;
  2. element.outerHTML = “…”;
  3. document.write(…);
  4. document.writeln(…);

5、 理解贯穿JS代码中不可信数据的数据流,如果你必须使用4中的接口,请务必记住先执行HTML转义,后执行JS转义。

6、 关于eval()和不可信数据。

7、 限定不可信数据只作为右边值操作。作为左边值可以被执行,例如location, eval()

var x = “<%=properly encoded data for flow%>”;

8、DOM中的URL转义需要注意字符集问题。

9、Limit access to properties objects when using object[x] accessors.

10、 在ECMAScript 5沙箱中运行JS代码,是的JS接口不被危害。

11、Don’t eval() JSON to convert it to native JavaScript objects. Instead use JSON.toJSON() and JSON.parse()

减轻DOM Based XSS攻击的常见问题

复杂上下文

一个点有两层含义, 首先是JS变量, 其次对于目标应用是URL

<a href=”javascript:myFunction(‘<%=Encoder.encodeForJS( ↩ Encoder.encodeForURL(untrustedData))%>’, 'test');”>Click Me</a>
...
<script>
Function myFunction (url,name) {
window.location = url;
}
</script>

如果客户端使用了JS版本的URL转义库,可以做如下写法

<!--server side URL encoding has been removed.  Now only JavaScript encoding on server side. -->
<a href=”javascript:myFunction(‘<%=Encoder.encodeForJS(untrustedData)%>’, 'test');”>Click Me</a>
...
<script>
Function myFunction (url,name) {
var encodedURL = ESAPI4JS.encodeForURL(url); //URL encoding using client-side scripts
window.location = encodedURL;
}
</script>

转义库不一致性

有多种开源库,每种实现有差异

  1. ESAPI
  2. Apache Commons String Utils
  3. Jtidy
  4. Your company’s custom implementation.

转义误解

不是说转义后就绝对安全,例如

1 下面代码在 content-type 为 xhtml文档中可以执行

<script>
alert(1);
</script>

2 下面代码,转义丢失, 接口执行可以绘制任何DOM

<form name=”myForm” …>
<input type=”text” name=”lName” value=”<%=Encoder.encodeForHTML(last_name)%>”>

</form>
<script>
var x = document.myForm.lName.value; //when the value is retrieved the encoding is reversed
document.writeln(x); //any code passed into lName is now executable.
</script>

通常安全方法

通常认为 innerText 不会执行代码, 可以代替innerHTML减轻XSS攻击,但是也依赖标签, 下面例子可以执行代码

<script>
var tag = document.createElement(“script”);
tag.innerText = “<%=untrustedData%>”; //executes code
</script>

DOM based XSS Prevention Cheat Sheet(DOM Based XSS防御检查单)的更多相关文章

  1. XSS (Cross Site Scripting) Prevention Cheat Sheet(XSS防护检查单)

    本文是 XSS防御检查单的翻译版本 https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sh ...

  2. XSS Filter Evasion Cheat Sheet 中文版

    前言 译者注: 翻译本文的最初原因是当我自己看到这篇文章后,觉得它是非常有价值.但是这么著名的一个备忘录却一直没有人把它翻译成中文版.很多人仅仅是简单的把文中的 各种代码复制下来,然后看起来很刁的发在 ...

  3. XSS Cheat Sheet(basics and advanced)

    XSS Cheat Sheet BASICS HTML注入 当输入位于HTML标记的属性值内或标记的外部(下一种情况中描述的标记除外)时使用.如果输入在HTML注释中,则在payload前加上&quo ...

  4. XSS Cheat Sheet

    Basic and advanced exploits for XSS proofs and attacks. Work in progress, bookmark it. Technique Vec ...

  5. IOS Application Security Testing Cheat Sheet

    IOS Application Security Testing Cheat Sheet    [hide]  1 DRAFT CHEAT SHEET - WORK IN PROGRESS 2 Int ...

  6. [react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?

    壹 ❀ 引 虚拟DOM(Virtual DOM)在前端领域也算是老生常谈的话题了,若你了解过vue或者react一定避不开这个话题,因此虚拟DOM也算是面试中常问的一个点,那么通过本文,你将了解到如下 ...

  7. 锋利的jQuery--jQuery与DOM对象的互相转换,DOM的三种操作(读书笔记一)

    1.jQuery对象就是通过jQuery包装DOM对象后产生的对象.   2.jQuery对象和DOM对象的相互转换.   良好的书写风格: var $input=$("input" ...

  8. 转:PostgreSQL Cheat Sheet

    PostgreSQL Cheat Sheet CREATE DATABASE CREATE DATABASE dbName; CREATE TABLE (with auto numbering int ...

  9. Git Cheat Sheet

    Merge Undo git merge with conflicts $ git merge --abort Archive $ git archive --format zip --output ...

随机推荐

  1. Codeforces Testing Round #10 A. Forgotten Episode

    水题,注意数据范围 #include <iostream> using namespace std; int main(){ long long n,a; cin >> n; ...

  2. [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化

    11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...

  3. BZOJ 3732 题解

    3732: Network Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ...

  4. 【BZOJ】2729: [HNOI2012]排队

    题意 \(n\)个男生\(m\)个女生\(2\)个老师排列,任意两个女生不能相邻,两个老师也不能相邻,每个人都不同.问有多少种排法.(\(n, m \le 2000\)) 分析 组合乱搞. 题解 先放 ...

  5. IOS 网络请求方式

    iOS开发中的网络请求   今天来说说关于iOS开发过程中的网络请求. 关于网络请求的重要性我想不用多说了吧.对于移动客户端来说,网络的重要性不言而喻.常见的网络请求有同步GET, 同步POST, 异 ...

  6. Bouncy Castle内存溢出

    现象: 堆内存溢出,java.lang.OutOfMemoryError: Java heap space 用jmap查看,显示 num     #instances         #bytes   ...

  7. GO语言练习:struct基础练习

    1.代码 2.运行 1.代码 package main import "fmt" type Rect struct { x, y float64 width, height flo ...

  8. C#读取文本播放相应语音【转】

    第一种方案: 利用微软text to speech引擎(TTS),读取文本 (1)添加Microsoft Speech Object Library的项目引用 (2)引入using SpeechLib ...

  9. EditText自定义边框

    1.EditText代码如下 (View代替EditText获取焦点): <View android:focusable="true" android:focusableIn ...

  10. android-发送短信