Researchers at Aretiq AI discovered
A vulnerability exists in Apache OFBiz’s login authentication workflow that allows an attacker to bypass a forced password-change restriction and achieve remote code execution. When an administrator sets the requirePasswordChange flag on a user account — for example after a credential leak, during new employee onboarding, or as a default on demo accounts — the account is supposed to be locked out of all functionality until the user changes their password through the dedicated ChangePassword form. However, LoginWorker.checkLogin() fails to recognize "requirePasswordChange" as an authentication failure, treating it identically to a successful login. An attacker who knows the current password of a locked account can bypass the restriction by injecting requirePasswordChange=Y as an HTTP request parameter along with a new password, causing the login and password change to execute inline and granting immediate access to the requested endpoint. Combined with ProgramExport.groovy lacking permission checks and a Groovy sandbox in versions prior to 24.09.06, this enables arbitrary OS command execution in a single HTTP request. Apache addressed this vulnerability in version 24.09.06.
The vulnerability requires two flaws in combination:
CWE-287 (Improper Authentication): checkLogin() only validates against the "error" string, treating a "requirePasswordChange" return from login() as successful authentication. This means requests that trigger the password-change path are not rejected at the auth check level.
CWE-287 (Client-Controlled Auth Flow): The requirePasswordChange flag is read from the HTTP request parameter (attacker-controlled) rather than exclusively from the database. This allows the attacker to inject the password-change flow into the auth check of ANY endpoint — not just the login/ChangePassword endpoint.
Combined, these flaws let an attacker submit credentials + password change + target request to any auth-protected endpoint in a single POST, bypassing the normal ChangePassword form routing. The unsandboxed ProgramExport endpoint (CWE-306 + CWE-94) — which lacks both permission checks and a Groovy code sandbox — amplifies the impact from an auth workflow bypass to full remote code execution.
Note: CVE-2023-51467, which exploits the same underlying requirePasswordChange logic flaw, was scored 9.8 by MITRE/NVD.
All Apache OFBiz releases prior to 24.09.06 are affected, including the entire 18.12.x branch and the 24.09.x series through 24.09.05.
The vulnerability combines two authentication flaws (#1 + #2) to bypass the forced password-change workflow, then chains with a third flaw (#3) to escalate from workflow bypass to RCE. Flaws #1 and #2 together constitute CVE-2026-45434; flaw #3 amplifies the impact.
Flaw 1: checkLogin() only validates against "error" (LoginWorker.java, checkLogin+0x163 )
The checkLogin() method delegates authentication to login() and checks its return value inside an OR-chain conditional:
The login() method can return three distinct values: "success" , "error" , or "requirePasswordChange" . Because checkLogin() only tests for "error" , a "requirePasswordChange" return evaluates as "error".equals("requirePasswordChange") → false , causing checkLogin() to fall through and return "success" .
Flaw 2: requirePasswordChange read from attacker-controlled request parameter (LoginWorker.java, login+0x33 )
Inside login() , the password-change flag is read directly from the HTTP request:
This allows an attacker to inject requirePasswordChange=Y into any login request. When the userLogin service validates the credentials successfully and the attacker provides newPassword / newPasswordVerify , the password change succeeds, doMainLogin() is called, and a fully authenticated session is established.
The login() method returns the result of doMainLogin() (which is "success" ), and checkLogin() correctly passes through. The net effect is that the attacker authenticates, changes the password to their chosen value, and accesses the target endpoint — all in a single HTTP request.
Flaw 3: ProgramExport lacks permission checks and Groovy sandbox (ProgramExport.groovy)
In OFBiz 24.09.05, ProgramExport.groovy evaluates user-supplied Groovy code with no restrictions:
There is no security.hasPermission() check, no SecureASTCustomizer , no receiver whitelist, and no dangerous-pattern regex blocklist. The attacker has full JVM access, including Runtime.getRuntime().exec() , ProcessBuilder , and Groovy’s .execute() string method.
How the flaws combine:
In the intended flow, when an account has requirePasswordChange=Y in the database, the user is forced through the ChangePassword form before accessing any other endpoint. The ChangePassword form only submits to the /login endpoint, which has response mappings that route the user back to the form or to the main page — never directly to an arbitrary endpoint like ProgramExport.
The exploit bypasses this by submitting requirePasswordChange=Y directly to ProgramExport (Flaw #2 — client-controlled parameter). The checkLogin() auth check for ProgramExport calls login() , which processes the inline password change and calls doMainLogin() . When login() returns, checkLogin() does not reject the result (Flaw #1 — only checks for "error" ), so the request proceeds directly to ProgramExport. The normal ChangePassword form routing is entirely skipped.
The unsandboxed ProgramExport (Flaw #3) then executes the attacker’s Groovy code with full JVM access, including OS command execution.
LoginWorker.java (OFBiz 24.09.05):
The vulnerable conditional at checkLogin() :
The client-controlled parameter at login() :
Call Stack (from OFBiz server log during exploit):
The fix consists of three commits:
Commit 6516157 — Remove client-controlled requirePasswordChange parameter:
Commit 771efc4 — Add ENTITY_MAINT permission check:
Commit c0592a3 — Add Groovy sandbox:
The patched ProgramExport.groovy adds:
Exploitation grants the attacker arbitrary OS command execution as the OFBiz process user. In the tested environment, OFBiz ran as root (uid=0), granting full system control. The attacker can read and modify all data in the OFBiz database (including user credentials, financial records, customer PII, and order data), install backdoors, pivot to other systems on the network, and completely compromise the business operations running on OFBiz.
The vulnerability is particularly severe because Apache OFBiz ships with over ten demo user accounts ( admin , flexadmin , demoadmin , ltdadmin , bizadmin , etc.) all sharing the well-documented default password ofbiz . Many deployments — especially development, staging, and recently-installed production instances — retain these default credentials. The vulnerability is also present in the Atlassian JIRA supply chain, as OFBiz was historically integrated into JIRA’s backend. Any internet-facing OFBiz instance with default or known credentials is trivially exploitable with a single HTTP request.
Download poc_cve_2026_45434.py (enterprise email verification required)
Setup (vulnerable target):
Verify the target is running:
Set requirePasswordChange=Y on the target account (simulating an admin lockdown). This can be done via the OFBiz admin UI (Party Manager → User Login → Edit) or via SQL/Groovy if you have another admin session:
Verify normal login is blocked — the account cannot access ProgramExport:
Run the exploit — bypass the restriction and execute code in one request:
Note: The exploit changes the password of the target user account as a side effect (the requirePasswordChange=Y request parameter triggers an inline password change as part of the bypass). The default new password is Pwn3d!12345 . Use the -u , -p , and --new-password flags to control which account is used and what the new password is set to.
Test environment: Apache OFBiz 24.09.05 on OpenJDK 17.0.18 (Ubuntu 24.04, containerized)
Setup: requirePasswordChange=Y set on ltdadmin1 account via admin Groovy (simulating admin-enforced password change lockout).
Tests A and B confirm the account is properly locked behind the forced password change — neither session-based nor direct-POST login grants access to ProgramExport. Test C demonstrates the exploit bypasses this restriction and achieves RCE in a single request.
Apache OFBiz 24.09.06 addresses the vulnerability through three complementary fixes:
With 24.09.06, the same PoC request returns HTTP 401 (Unauthorized) and no Groovy code is executed.
Note: The detection rules below are provided as a starting point. Validate and tune them in your own environment before deploying to production.
The attack is identifiable by the following characteristics in a single HTTP POST request:
The combination of requirePasswordChange=Y with groovyProgram in a single request to ProgramExport is not seen in legitimate OFBiz usage — normal password changes go through the ChangePassword form, which does not submit Groovy code.
The following YARA rules detect vulnerable and patched versions of the affected OFBiz source and compiled files. Because OFBiz is a Java application distributed as source + compiled classes in JARs, these rules target string patterns present in the Java source files and compiled .class bytecode (Java class files embed method names, string literals, and class references as UTF-8 constants).
Matches the vulnerable LoginWorker.java pattern where requirePasswordChange is read from the HTTP request parameter (client-controlled) and the checkLogin() method only compares against the "error" string:
Matches patterns unique to the patched LoginWorker.java (24.09.06+), where the requirePasswordChange flag is read from the database entity instead of the HTTP request, and the login() method no longer returns "requirePasswordChange" :
Detects whether ProgramExport.groovy has the Groovy sandbox applied (patched) or is unsandboxed (vulnerable):
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
