This article is a translated version, please see the original Https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet
Introduction
Speaking of XSS attacks, there are three accepted forms of Stored, reflected, and DOM Based XSS.
XSS prevention Cheatsheet can effectively solve Stored, reflected XSS attacks, this checklist solves the DOM Based XSS attack, is an extension of XSS prevention Cheatsheet.
To understand Dom Based XSS attacks, you need to understand the fundamental difference between reflected and stored XSS attacks and Dom Based XS.
Reflected and Stored XSS is a problem with server-side code execution, and DOM based XSS is a problem with browser-side code execution.
All of the code comes from the server, which means that the application owner is responsible for ensuring that the app is protected from XSS attacks, regardless of the type of XSS attack.
When the browser renders HTML and other associated content, such as CSS JS etc, it uses different rules for each different context to render.
The HTML parser is responsible for how the data is displayed and how it is laid out on the page, and further decomposed into standard environments, such as HTML HTML property URLs and CSS. The JavaScript or VBScript parser is responsible for parsing and executing script code, and each parser has a different syntax, which makes it difficult to create uniform rules for preventing vulnerabilities. The complex point lies in the mixing of different meanings and the processing methods of each seed environment (HTML, HTML attribute, URL, and CSS) for transcoding.
This article defines HTML, HTML attribute, URLs, and CSS environments as sub-environments, because each environment can be accessed and executed by the JS environment.
In the JS code, the main environment is JS, but through the right tag and the environment close character, the attacker can attack the other four environments, using the same meaning of the JS Dom method.
Here is an example of a vulnerability, which occurs in the JS environment due to an attack on the HTML sub-environment:
<script>var x = ' <%= taintedvar%> '; var d = document.createelement (' div ');d. InnerHTML = x; Document.body.appendChild (d);</script>
Let's take a look at each sub-environment below.
Rule # # # # before inserting the non-trusted data into HTML in the script, perform the HTML escape and then the JS escape
There are several methods and properties that can render the HTML environment directly in JS, and if these methods and properties encounter untrusted data, then an XSS vulnerability occurs.
For example
--Properties
element.innerhtml = "<HTML> tags and markup"; element.outerhtml = "<HTML> tags and markup";
--Method
document.write ("<HTML> tags and Markup");d Ocument.writeln ("<HTML> tags and markup");
Guidelines and guidelines
To ensure that HTML in a dynamically updated DOM is secure, we recommend that untrusted data be
A) HTML encoding
b) JS Code
As shown in the following examples
element.innerhtml = "<%=encoder.encodeforjs (encoder.encodeforhtml (untrusteddata))%>"; Element.outerHTML = " <%=encoder.encodeforjs (encoder.encodeforhtml (untrusteddata))%> ";
document.write ("<%=encoder.encodeforjs (encoder.encodeforhtml (untrusteddata))%>");d Ocument.writeln ("<% =encoder.encodeforjs (encoder.encodeforhtml (untrusteddata))%> ");
Note: encoder.encodeforhtml () and Encoder.encodeforjs () are just the names of the encoders, where the implementation is described later in this article.
Rule # # # # # # # # # # # before inserting non-trusted data into HTML properties in a script
For properties that do not execute code, that is, non-event handler, CSS, and URL attributes, you only need to JS escape the attribute values in 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);
Also, the following example indicates that if the HTML transcoding is incorrect, if the value is set to "Johnson & Johnson" and is HTML transcoded, the result is "Johnson & Johnson ". Note that using the DOM property interface to modify the DOM does not apply HTML parsing rules.
var x = document.createelement ("input"); X.setattribute ("Name", "Company_Name");//In the following line of code, Companyn AME represents untrusted User input//the encoder.encodeforhtmlattr () is unnecessary and causes double-encodingx.setattri Bute ("Value", ' <%=encoder.encodeforjs (encoder.encodeforhtmlattr (companyName))%> '); var Form1 = Document.forms[0];form1.appendchild (x);
Rule # # Insert untrusted data into the event handling handle and JS code, be careful
It is particularly dangerous to put dynamic data into JS code, because JS coding has different semantics, compared to other environment coding.
In many cases, JS transcoding does not prevent code from being executed. Therefore, the first recommendation is not to insert untrusted data into the JS code. The following code demonstrates a situation where there is still a risk of escaping:
var x = document.createelement ("a"); x.href= "#";//in the line of code below, the encoded data on the right (the second arg Ument to SetAttribute)//are an example of untrusted data, was properly JavaScript encoded but still Executes.x.setatt Ribute ("onclick", "\u0061\u006c\u0065\u0072\u0074\u0028\u0032\u0032\u0029"); var y = document.createTextNode ("click to Test "); X.appendchild (y);d ocument.body.appendChild (x);
This is because these methods all use the JS string as the JS code and execute it. Other methods with the same risk (SetTimeout, setinterval, new Function, etc).
Rule # # to insert untrusted data into a CSS property before inserting the JS escape
No research is pending.
Rule # # # before inserting untrusted data into a URL property, perform a URL escape and then execute JS escape
No research is pending.
using JS to develop safety application guidelines
DOM based XSS and its difficult to eradicate, because its attack surface is very wide, and cross-browser standardization. The following is a guide to help developers develop JS applications to reduce XSS vulnerabilities.
1. Untrusted data should be displayed as text only and should not be executed as a JS code or tag.
2, the untrusted data always use JS escape, and add quotation marks method, let it appear in the JS code.
var x = "<%=encodedJavaScriptData%>";
3, use document.createElement(“…”), element.setAttribute(“…”,”value”), element.appendChild(…)
, etc. To create a dynamic interface. Among them, is setAttribute
not particularly safe, for some of the values as JS code properties, there are security risks, such as onclick or onblur, other security attributes include Align, ALink, Alt, bgcolor, border, cellpadding , cellspacing, class, color, cols, colspan, coords, dir, face, height, hspace, ismap, Lang, marginheight, Marginwidth, Mul Tiple, Nohref, Noresize, NoShade, nowrap, ref, REL, rev, rows, rowspan, scrolling, shape, span, summary, TabIndex, title, Usemap, valign, value, Vlink, vspace, Width
4. Avoid using HTML rendering methods
element.innerHTML = “…”;
element.outerHTML = “…”;
document.write(…);
document.writeln(…);
5, understand the data flow through the JS code in the non-trusted data, if you must use the interface in 4, it is important to remember to perform HTML escape, after the execution of JS escape.
6, about Eval () and non-trusted data.
7, limit the non-trusted data only as the right value operation. As the left value can be executed, for example location
,eval()
var x = "<%=properly encoded data for flow%>";
8. URL escaping in the DOM requires attention to character set issues.
9, Limit access to the properties objects when using object[x] accessors.
10, in the ECMAScript 5 sandbox running JS code, yes JS interface is not compromised.
11, Don ' t eval()
JSON to convert it to native JavaScript objects. Instead Use and JSON.toJSON()
JSON.parse()
frequently asked questions about mitigating Dom Based XSS attacksComplex Context
A point has two meanings, first the JS variable, and then the URL for the target application.
<a href= "Javascript:myfunction (' <%=encoder.encodeforjs (? Encoder.encodeforurl (untrusteddata))%> ', ' test '); " >click me</a>...<script>function myFunction (url,name) { window.location = URL;} </script>
If the client uses the JS version of the URL escape library, you can do the following
<!--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>
Escape Library Inconsistencies
There are a variety of open source libraries, each with different implementations
- Esapi
- Apache Commons String Utils
- Jtidy
- Your company ' s custom implementation.
Escape Misunderstanding
It's not that it's absolutely safe after escaping, for example
1 The following code can be executed in Content-type as an XHTML document
<script>& #x61 Lert (1);</script>
2 The following code, Escape is lost, interface execution can draw any 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 was retrieved the encoding is Reverseddocument.writeln (x); Any code passed to LName are now executable.</script>
Common Security methods
It is generally assumed that InnerText does not execute code and can mitigate XSS attacks instead of innerHTML, but also relies on tags, and the following example can execute code
<script>var tag = document.createelement ("script"); tag.innertext = "<%=untrustedData%>"; Executes code</script>
Dom based XSS Prevention Cheat Sheet (DOM based XSS defense Checklist)