53 lines
2.3 KiB
Plaintext
Raw Normal View History

== How to fix it in DOM API
=== Code examples
The following code is vulnerable to DOM-based cross-site scripting because it uses unsanitized URL parameters to alter the DOM of its webpage.
Because the user input is not sanitized here and the used DOM property is vulnerable to XSS, it is possible to inject arbitrary code in the user's browser through this example.
==== Noncompliant code example
The https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML[``Element.innerHTML``] property is used to replace the contents of the `root` element with user-supplied contents. The `innerHTML` property does not sanitize its input, thus allowing for code injection.
[source,javascript,diff-id=1,diff-type=noncompliant]
----
const rootEl = document.getElementById('root');
const queryParams = new URLSearchParams(document.location.search);
const input = queryParams.get("input");
rootEl.innerHTML = input; // Noncompliant
----
==== Compliant solution
The https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText[``HTMLElement.innerText``] property does not create DOM elements out of its input, rather treating its input as a string. This makes it a safe alternative to `Element.innerHTML` depending on the use case.
[source,javascript,diff-id=1,diff-type=compliant]
----
const rootEl = document.getElementById('root');
const queryParams = new URLSearchParams(document.location.search);
const input = queryParams.get("input");
rootEl.innerText = input;
----
=== How does this work?
In general, one should limit the use of dangerous properties and methods, such as `Element.innerHTML` or `Document.write()`, as there exist many ways for an attacker to exploit their usage. Instead, prefer the usage of safe alternatives such as `HTMLElement.innerText` or `Node.textContent`. Furthermore, frameworks such as React or Vue.js will automatically escape variables used in views, making it much harder to accidentally write vulnerable code.
If these options are not possible, sanitization of the attacker-controllable input should be preferred.
include::../../common/fix/sanitization.adoc[]
=== Pitfalls
include::../../common/pitfalls/limits-of-validation.adoc[]
include::../../common/pitfalls/modification-after-sanitization.adoc[]
=== Going the extra mile
include::../../common/extra-mile/csp.adoc[]