Exploiting DOM clobbering to enable XSS

Description

This lab contains a DOM-clobbering vulnerability. The comment functionality allows “safe” HTML.

Reproduction and proof of concept

  1. Analysis:

The site uses the DOMPurify filter in an attempt to reduce DOM-based vulnerabilities.DOMPurify allows for the use of the cid: protocol, which does not URL-encode double-quotes. This means an encoded double-quote can be injected that will be decoded at runtime. As a result, an injection can cause the defaultAvatar variable to be assigned the clobbered property {avatar: ‘cid:"onerror=alert(1)//’} the next time the page is loaded.

The defaultAvatar object is implemented using this dangerous pattern containing the logical OR operator in conjunction with a global variable. This makes it vulnerable to DOM clobbering.

This object can be clobbered using anchor tags. Creating two anchors with the same ID causes them to be grouped in a DOM collection. The name attribute in the second anchor contains the value avatar, which will clobber the avatar property with the contents of the href attribute.

  1. Go to one of the blog posts and create a comment containing the following anchors:

<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">
  1. Return to the blog post and create a second comment containing any random text. The next time the page loads, the alert() is called.

The page for a specific blog post imports the JavaScript file loadCommentsWithDomPurify.js, which contains the following code:

let defaultAvatar = window.defaultAvatar || {avatar: '/resources/images/avatarDefault.svg'}

When you make a second post, the browser uses the newly-clobbered global variable, which smuggles the payload in the onerror event handler and triggers the alert().

Exploitability

To solve this lab, an attacker will need to construct an HTML injection that clobbers a variable and uses XSS to call the alert() function.