Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lexical] Bug Fix: DOM Clobbering Gadget found in rollup bundled scripts that leads to XSS #6756

Closed
wants to merge 1 commit into from

Conversation

lamcodeofpwnosec
Copy link

We discovered a DOM Clobbering vulnerability in rollup when bundling scripts that use import.meta.url or with plugins that emit and reference asset files from code in cjs/umd/iife format. The DOM Clobbering gadget 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.

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:

Gadget found in rollup
We have identified a DOM Clobbering vulnerability in rollup bundled scripts, particularly when the scripts uses import.meta and set output in format of cjs/umd/iife. In such cases, rollup replaces meta property with the URL retrieved from document.currentScript.

PoC

Considering a website that contains the following main.js script, the devloper decides to use the rollup to bundle up the program: rollup main.js --format cjs --file bundle.js.

var s = document.createElement('script')
s.src = import.meta.url + 'extra.js'
document.head.append(s)

The output bundle.js is shown in the following code snippet.

'use strict';

var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
var s = document.createElement('script');
s.src = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && False && _documentCurrentScript.src || new URL('bundle.js', document.baseURI).href)) + 'extra.js';
document.head.append(s);

Patch
Patching the following two functions with type checking would be effective mitigations against DOM Clobbering attack.

const getRelativeUrlFromDocument = (relativePath: string, umd = false) =>
	getResolveUrl(
		`'${escapeId(relativePath)}', ${
			umd ? `typeof document === 'undefined' ? location.href : ` : ''
		}document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || document.baseURI`
	);
const getUrlFromDocument = (chunkId: string, umd = false) =>
	`${
		umd ? `typeof document === 'undefined' ? location.href : ` : ''
	}(${DOCUMENT_CURRENT_SCRIPT} && ${DOCUMENT_CURRENT_SCRIPT}.tagName.toUpperCase() === 'SCRIPT' &&${DOCUMENT_CURRENT_SCRIPT}.src || new URL('${escapeId(
		chunkId
	)}', document.baseURI).href)`;

Impact

This vulnerability can result in cross-site scripting (XSS) attacks on websites that include rollup-bundled files (configured with an output format of cjs, iife, or umd and use import.meta) and allow users to inject certain scriptless HTML tags without properly sanitizing the name or id attributes.

CVE-2024-47068
CWE-79

Copy link

vercel bot commented Oct 23, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
lexical ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 23, 2024 8:47am
lexical-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 23, 2024 8:47am

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 23, 2024
Copy link

size-limit report 📦

Path Size
lexical - cjs 29.94 KB (0%)
lexical - esm 29.78 KB (0%)
@lexical/rich-text - cjs 38.6 KB (0%)
@lexical/rich-text - esm 31.64 KB (0%)
@lexical/plain-text - cjs 37.2 KB (0%)
@lexical/plain-text - esm 29 KB (0%)
@lexical/react - cjs 40.34 KB (0%)
@lexical/react - esm 33 KB (0%)

@potatowagon potatowagon added the extended-tests Run extended e2e tests on a PR label Oct 25, 2024
@@ -1,21 +1,21 @@
{
"name": "lexical-esm-astro-react",
"version": "0.17.1",
"version": "0.18.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi i see a couple of dependency updates in the test fixtures lexical-esm-astro-react package-lock.json.

could u help me understand which dependencies in particular introduced this vulnerability?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's just rollup, we are probably better off fixing this in package.json and it's not in an area that's deployed anywhere so probably not urgent

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @potatowagon

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/

PoC
Considering a website that contains the following main.js script, the devloper decides to use the rollup to bundle up the program: rollup main.js --format cjs --file bundle.js.

var s = document.createElement('script')
s.src = import.meta.url + 'extra.js'
document.head.append(s)

Rollup is a module bundler for JavaScript. Versions prior to 3.29.5 and 4.22.4 are susceptible to a DOM Clobbering vulnerability when bundling scripts with properties from import.meta (e.g., import.meta.url) in cjs/umd/iife format. The DOM Clobbering gadget 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. Versions 3.29.5 and 4.22.4 contain a patch for the vulnerability.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's just rollup, we are probably better off fixing this in package.json and it's not in an area that's deployed anywhere so probably not urgent

got it about rollup. i did receive an alert about the same vulnerablity. have updated rollup here: #6764

im not too sure what this PR is doing, eg. why only target scripts/tests/integration/fixtures/lexical-esm-astro-react/package-lock.json, and why "node_modules/yjs" being deleted

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ill close this PR first since rollup vulnerablity is addressed in another PR. if this PR has to be reopen, please add the steps done to generate the changes (eg. cmds ran)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants