Skip to main content
Vulnerability Database/CVE-2026-94411

CVE-2026-94411: jshERP Privilege Escalation Vulnerability

CVE-2026-94411 is a privilege escalation flaw in jshERP 3.6 that lets authenticated users grant themselves administrator roles via the updateOneValueByKeyIdAndType endpoint. This article covers technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-94411 Overview

CVE-2026-94411 is a privilege escalation vulnerability in jshERP 3.6, an open-source enterprise resource planning platform. The flaw resides in the updateOneValueByKeyIdAndType endpoint exposed by UserBusinessController. Authenticated low-privilege tenant users can send a crafted POST request supplying type=UserRole, their own user identifier, and an arbitrary role identifier list. The server persists the submitted role assignment without verifying that the caller is authorized to modify role membership. An attacker exploits this behavior to escalate from a standard tenant account to tenant administrator, gaining full control over ERP data and workflows. The issue is tracked under CWE-862: Missing Authorization.

Critical Impact

Any authenticated tenant user can promote themselves to tenant administrator with a single HTTP request, resulting in complete tenant compromise.

Affected Products

  • jshERP version 3.6
  • UserBusinessController component in jshERP-boot
  • Deployments exposing the updateOneValueByKeyIdAndType endpoint to authenticated users

Discovery Timeline

  • 2026-09-21 - CVE-2026-94411 published to NVD
  • 2026-09-22 - Last updated in NVD database

Technical Details for CVE-2026-94411

Vulnerability Analysis

The vulnerable logic lives in the UserBusinessController class within the jshERP Spring Boot backend. The updateOneValueByKeyIdAndType handler accepts three parameters: type, keyId, and value. When type=UserRole is supplied, the controller writes the provided value (a list of role IDs) to the user identified by keyId. The controller performs no server-side check confirming the caller has administrative rights over user-role assignments. It also does not confirm that keyId corresponds to an object the caller is entitled to modify. As a result, a standard tenant user can pass their own user ID and any role ID, including the tenant administrator role, and the change is committed to the database.

Root Cause

The defect is a missing authorization check [CWE-862]. Authentication is enforced at the request layer, but the endpoint lacks a role-based access control decision before mutating privileged records. Business logic that should be restricted to tenant administrators is reachable by any authenticated session.

Attack Vector

Exploitation requires network access to the jshERP web interface and valid low-privilege credentials. The attacker issues a single POST request to updateOneValueByKeyIdAndType with type=UserRole, keyId set to their own user ID, and value set to a JSON list containing the tenant administrator role ID. After the request succeeds, the attacker reauthenticates or refreshes their session to inherit administrator privileges. A public proof-of-concept script is published at the GitHub PoC repository, and the vulnerable code path is visible in the UserBusinessController source.

Detection Methods for CVE-2026-94411

Indicators of Compromise

  • POST requests to /user/updateOneValueByKeyIdAndType containing the parameter type=UserRole originating from non-administrative accounts.
  • Database changes in the jsh_user_business table that assign administrator role IDs to previously low-privilege users without a corresponding administrative action in the audit log.
  • Sudden appearance of new tenant administrators followed by bulk data export, user creation, or configuration changes.

Detection Strategies

  • Inspect application access logs for calls to updateOneValueByKeyIdAndType where the authenticated principal does not match a known administrator account.
  • Correlate role-assignment events with the authenticated user ID to identify self-modification, where the caller and the keyId are the same non-administrator account.
  • Baseline expected administrator counts per tenant and alert on unexpected growth.

Monitoring Recommendations

  • Forward jshERP application logs, reverse proxy logs, and database audit trails to a centralized SIEM for correlation.
  • Enable query auditing on the user-role tables so writes are logged with the executing session identity.
  • Alert on any HTTP 200 response to updateOneValueByKeyIdAndType calls containing the UserRole type parameter.

How to Mitigate CVE-2026-94411

Immediate Actions Required

  • Restrict network access to the jshERP application so only trusted internal users can reach the web interface.
  • Review the jsh_user_business table for unauthorized administrator assignments and revoke elevated roles from unexpected accounts.
  • Rotate credentials for accounts that received unauthorized privilege changes and invalidate active sessions.
  • Monitor the jshERP repository and the VulnCheck advisory for an official patched release.

Patch Information

No vendor-supplied patch is referenced in the published advisory at the time of writing. Operators running jshERP 3.6 should track the upstream project for a fixed release and apply it as soon as it becomes available. Until then, apply compensating controls at the reverse proxy or application gateway.

Workarounds

  • Block or filter requests to updateOneValueByKeyIdAndType at a reverse proxy or web application firewall when the caller is not a known administrator.
  • Add a server-side authorization check in a locally maintained fork of UserBusinessController to reject requests where type=UserRole unless the caller holds an administrative role.
  • Segment jshERP deployments so tenant users only reach the application over authenticated VPN or zero-trust access paths, reducing exposure to untrusted networks.
bash
# Example reverse-proxy rule to block non-admin role modifications
# nginx snippet - adjust admin allowlist and location path to your deployment
location /user/updateOneValueByKeyIdAndType {
    if ($arg_type = "UserRole") {
        return 403;
    }
    proxy_pass http://jsherp_backend;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.