Preventing DOM based XSS using ESAPI

2.4k Views Asked by At

According to OWASP, to make dynamic updates to HTML in the DOM safe, we recommend

  1. HTML encoding, and then
  2. JavaScript encoding all untrusted input, as shown in these examples: element.innerHTML = “<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”;

There is a web application where the servlet receives the user input(received as an AJAX request) ,process the data and sends a text response which is used to change the DOM dynamically by setting the value of an element(using document.getElementById("elementID").innerHTML = data;).

To prevent DOM based XSS is it required to escape the HTML and JavaScript using the ESAPI encoder as

String htmlEscapedStr=ESAPI.encoder().encodeForHTML(content);
String JSEscapedStr=ESAPI.encoder().encodeForJavaScript(htmlEscapedStr);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(JSEscapedStr);

;

or is it safe to write the unencoded String to the stream

response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(content);
1

There are 1 best solutions below

2
On BEST ANSWER

I'm assuming content is plain text and you do not wish to ever contain HTML in your content itself. You do not need to encode for JavaScript as the value is not being injected into JavaScript, it is simply being used by JavaScript in a JavaScript context to set innerHTML. So the correct way is:

String htmlEscapedStr=ESAPI.encoder().encodeForHTML(content);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(htmlEscapedStr);

The content type being left as text/plain is fine in this context as the application receiving the data (your webpage) does not have to interpret the content type itself as it is simply setting innerHTML to the returned value.

or is it safe to write the unencoded String to the stream

If content contains any "untrusted" data (for "untrusted" read "from user input" or "from external source") then potentially it could contain script code as part of an XSS attack. If it is from a trusted source, but it is formatted as plain text then characters such as < could break the formatting of your output but would not cause a security issue. For example a mathematical expression such as 1 < 2 > 1.5 would be output as 1 1.5 in the browser.