# How to check your Apache OFBiz runs 24.09.08, the release that fixes two pre-login RCEs

URL: https://systemdesignsimple.com/apache-ofbiz-rce-check-and-fix/
Published: 2026-11-07
Category: Security
Publisher: System Design Simple (https://systemdesignsimple.com)

## Short answer

Every Apache OFBiz release before 24.09.08 has two remote code execution flaws reachable without an authenticated user: CVE-2026-83542 (CVSS 9.8) and CVE-2026-68524. Upgrade to 24.09.08. Check the version from a clean git tag or the verified release zip, because the VERSION file only says 24.09, then deploy into a new release directory, restart from it and record the source commit.

## Key facts

- **CVEs:** CVE-2026-83542 (CVSS 3.1 9.8) and CVE-2026-68524 (rated important), both CWE-94
- **Affected:** every Apache OFBiz release before 24.09.08, all platforms
- **Fixed in:** 24.09.08 (released November 2026), which fixes 46 CVEs in total
- **Published:** both CVE records published 2026-11-05
- **Exploitation:** CISA ADP enrichment of CVE-2026-83542, 2026-11-06: exploitation none, automatable yes, technical impact total
- **Mitigation:** no alternative mitigation is specified; upgrade is recommended
- **Our lab:** 16 synthetic version fixtures: 9/9 old records classified, 9/9 ok after the record change, 7/7 normal fixtures unchanged

Every Apache OFBiz release before 24.09.08 lets a request without an authenticated user make the server load widget XML the requester supplied and evaluate the Groovy inside it (CVE-2026-83542, CVSS 9.8, and CVE-2026-68524). Upgrade to 24.09.08 today. Confirm it from a clean git tag or the verified release zip and from how the service was actually started, because the VERSION file in the fixed release only says `24.09`.

This guide is for protecting OFBiz installations you own or maintain.

| | CVE-2026-83542 | CVE-2026-68524 |
|---|---|---|
| Entry point | login-page widget, decorator location shadowed by request data | screen definition loaded through an injected `file:` URI |
| Severity | CVSS 3.1 9.8, AV:N/AC:L/PR:N/UI:N | "important" (no CVSS from the CNA) |
| Weakness | CWE-94 code injection | CWE-94 code injection |
| Affected | all versions before 24.09.08 | all versions before 24.09.08 |
| Fixed | 24.09.08 | 24.09.08 |
| Published | 2026-11-05 | 2026-11-05 |

## Why it is dangerous

OFBiz renders pages from XML screen definitions. A screen names its decorator and included screens by location, normally a `component://` URI, and widget attributes can carry Groovy expressions that run at render time. Whoever controls a location string controls which code the renderer evaluates.

The trusted locations, such as `mainDecoratorLocation`, come from the webapp configuration in `web.xml` and live as servlet context attributes. Before the fix, `WebAppUtil.setAttributesFromRequestBody` copied every key of a JSON request body into request attributes, and a request attribute with the same name shadows the context value when the screen looks it up. According to the [CVE-2026-83542 record](https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/83xxx/CVE-2026-83542.json), a crafted body could point the decorator used on the authentication-failure path at widget XML staged by an earlier upload, and the renderer evaluated its Groovy.

The requests execute without an authenticated user. The CVE-2026-68524 record describes temporary-file handling and an open file descriptor reached through an injected `file:` URI ([CVE-2026-68524 record](https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/68xxx/CVE-2026-68524.json)). Either way the result is code running as the OFBiz service user, with the database credentials in its configuration and anything else that user can read. CISA's enrichment of CVE-2026-83542 rates it automatable with total technical impact.

[PR #1654](https://github.com/apache/ofbiz-framework/pull/1654/files) closes both halves. The body copier now skips any key that already exists as a servlet context attribute and logs a warning, so request data can no longer stand in for configuration. Every widget load (screen, form, grid, menu, tree) now passes through `WidgetSecureLocation.sanitize()`: `file:` in any letter case is rejected, other URLs must be `component://`, `component://` paths containing `..` are rejected, and bare filesystem paths pass only if they match `security.allowFilePaths`, which is blank by default. That allowlist replaces an older blocklist entry for `proc/self/fd`. [PR #1653](https://github.com/apache/ofbiz-framework/pull/1653/files) is a separate layer: it filters request parameters ending in `Location`, `Screen`, `Template` or `Uri` before view state is saved in the session, so a value cannot be persisted and replayed on a later page.

## Am I affected?

Yes, if the OFBiz serving traffic was built from anything older than the `release24.09.08` tag. That includes all of 18.12. Read a record that names the patch release, and confirm the tree matches it:

```sh
# git checkout: the tag HEAD sits on (want release24.09.08 or later)
cd /opt/ofbiz
git describe --tags --exact-match 2>/dev/null || git describe --tags
git status --porcelain          # must print nothing, or the tag does not describe these files

# release zip: the archive you unpacked (want apache-ofbiz-24.09.08), not just the folder name
basename "$PWD"

# this prints only the branch, "24.09", even on the fixed tag
cat VERSION
```

A result like `release24.09.07-12-gabc1234` means 12 commits past 24.09.07 on some branch. Treat it as unknown until you check those commits, or move to the tag. A folder name is a hint; the zip's checksum and signature are the record.

## Fix it now

```sh
# git checkout (back up the database first)
git fetch --tags
git checkout release24.09.08
git status --porcelain            # empty before you build
git rev-parse HEAD                # record this commit
./gradlew build

# release zip: download apache-ofbiz-24.09.08.zip with its .sha512 and .asc
shasum -a 512 -c apache-ofbiz-24.09.08.zip.sha512
gpg --verify apache-ofbiz-24.09.08.zip.asc apache-ofbiz-24.09.08.zip

# container: the project's Dockerfile builds locally, so rebuild from the tag
git checkout release24.09.08
docker build --tag ofbiz-docker:24.09.08 .
```

Then check what is running, which is a different question from what is on disk:

```sh
# Linux host: take the PID from the service manager, not from a process-name search
pid=$(systemctl show -p MainPID --value ofbiz)
ps -o lstart= -p "$pid"             # confirms a restart only
tr '\0' ' ' < /proc/"$pid"/cmdline  # the actual launch command and classpath
readlink /proc/"$pid"/cwd           # the working directory

# container: compare image IDs, then check mounts
docker inspect --format '{{.Image}}' <container>
docker image inspect --format '{{.Id}}' ofbiz-docker:24.09.08
docker inspect --format '{{json .Mounts}}' <container>
```

These checks identify the working directory and current on-disk JAR. Verify the service's actual launch command and classpath, deploy the complete build into a new release directory, and restart from that directory. Record the source commit and deployment manifest. In a container, matching image IDs mean little if a mount replaces the application files, so check that no mount covers the OFBiz tree.

## What our lab checked

`ofbiz-version-check-lab` is a read-only version classifier. It runs no OFBiz code and sends no requests. It builds 16 synthetic OFBiz-shaped fixtures that hold only version records (a `VERSION` file, `gradle.properties`, the root `build.gradle`, a zip folder name, a git HEAD and tags), reads every version it finds and classifies the lowest one against an advisory. The lab advisory uses made-up branches 90.12 and 94.09 with fixes 90.12.4 and 94.09.2, so nobody mistakes them for real numbers.

| Check (run 2026-11-07 00:34 UTC, Node 22.13.1, this Mac) | Result |
|---|---|
| old-version fixtures classified as unsafe | 9/9 |
| same fixtures classified ok after the record change | 9/9 |
| normal fixtures unchanged | 7/7 |

Two cases mattered. A `94.09.2-SNAPSHOT` sorts below the release it precedes, so it is `OLD`. A fixture whose `VERSION` says 94.09.2 while git HEAD sits on tag `release94.09.1` is also `OLD`, because the lowest-wins rule trusts the older record. A `trunk` checkout with no version anywhere is `NOVER`, never ok.

[Image: Terminal output of our ofbiz-version-check-lab run: node ofbiz-version-check-lab.mjs | Synthetic version-classifier checks only. No OFBiz exploit or upgrade was tested. The capture's labels "attack inputs", "BLOCKED" and "FIX WORKS" mean fixtures, classification after record change and classifier checks passed.]

What this does not show: the lab performs no OFBiz upgrade, renders no screen and does not test that 24.09.08 blocks either CVE; that rests on the Apache advisory and the fix PRs. It also has a gap. The real [`VERSION` file on `release24.09.08`](https://raw.githubusercontent.com/apache/ofbiz-framework/release24.09.08/VERSION) reads `24.09`, and we have no fixture for a branch-only value yet. Our reader would treat it as 24.09.0 and call a correctly upgraded checkout `OLD`. The error is on the safe side, but until the lab treats branch-only values as incomplete evidence, use a clean `git describe` or the verified zip as your verdict on a real install.

## If you cannot update today

No alternative mitigation is specified; upgrade is recommended. Until the upgrade is deployed, restrict network access to the affected service. Both flaws are reached without login, so public routes count as much as admin pages. A request to `/` checks only that address and route; review every published listener and proxy route. From a host outside your network:

```sh
curl -sSk -o /dev/null -w '%{http_code}\n' --max-time 5 https://ofbiz.example.com:8443/
echo "curl exit status: $?"
```

`000` means no HTTP response arrived. DNS, TLS and timeout failures print it too, so read the exit status and error message; `000` alone does not prove the block works ([curl documentation](https://curl.se/libcurl/c/CURLINFO_RESPONSE_CODE.html)).

## Timeline and sources

| Date | Event |
|---|---|
| 2026-07-30 | CVE-2026-68524 reserved |
| 2026-08-14 | PRs #1653 and #1654 merged into `release24.09` |
| 2026-08-31 | CVE-2026-83542 reserved |
| November 2026 | 24.09.08 released ([download page](https://ofbiz.apache.org/download.html)); fixes 46 CVEs ([security page](https://ofbiz.apache.org/security.html)) |
| 2026-11-05 | both CVE records published |
| 2026-11-06 | CISA ADP enrichment of CVE-2026-83542: exploitation none, automatable yes |
| 2026-11-07 | our lab run |

## Our take

The OFBiz `VERSION` file names the branch, so on the tag that carries the fix it reads `24.09`, the same as every older 24.09 release. We found this by checking our own lab against the repository. Any inventory script or scanner that reads only `VERSION` cannot tell a patched OFBiz from an unpatched one. A clean tag, a verified zip and a recorded commit are the records that change with the patch.

The fix PRs merged into `release24.09` on August 14, months before the CVE records went public. A team building from the branch may already carry them without knowing, and a team on a pinned older tag does not, even though both say `24.09`. That is the same gap between "fix released" and "fix installed" we measured for [PHP and Node.js](/patched-but-not-updated-php-node-rce/), and the [WordPress](/wordpress-core-upgrade-flaw-check-and-fix/) and [PHP runtime](/php-rce-php2shell-check-and-fix/) checks follow the same order: version record first, then the running process.

Both CVEs cross the boundary between request data and executable screen resources. If you maintain custom OFBiz components, search them for request parameters ending in `Location`, `Screen`, `Template` or `Uri`, and for code that copies request bodies into attributes. The framework now guards its own path, and custom code can open a new one. The [Rails upload check](/rails-imagemagick-upload-flaw-check-and-fix/) is a related case, where an uploaded file was trusted as more than data.

## Frequently asked questions

**I build from the release24.09 branch. Do I already have the fix?**
PRs #1653 and #1654 merged into release24.09 on 2026-08-14, but 24.09.08 fixes 46 CVEs merged at different times. Pin to the tag release24.09.08 or later and record the deployed commit.

**We still run 18.12. Is there a patch for it?**
Both CVE records list every version before 24.09.08 as affected, and the security page names 24.09.08 as the fix. There is no 18.12 release for these, so the path is a move to 24.09.08.

**Our custom screens stopped loading after the upgrade. What changed?**
Widget locations are now checked before loading. Move widget resources into a component. For necessary bare filesystem paths, set a narrowly scoped security.allowFilePaths regular expression. file: URIs stay blocked.

## Sources

- [Apache OFBiz: Security (fixed release for every CVE)](https://ofbiz.apache.org/security.html)
- [CVE-2026-83542, CVE record (JSON): unauthenticated RCE via login-page widget injection](https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/83xxx/CVE-2026-83542.json)
- [CVE-2026-68524, CVE record (JSON): screen definition loaded through an injected file: URI](https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/68xxx/CVE-2026-68524.json)
- [apache/ofbiz-framework PR #1654: protect trusted attributes and check widget resource locations](https://github.com/apache/ofbiz-framework/pull/1654/files)
- [apache/ofbiz-framework PR #1653: filter location-like request parameters before session persistence](https://github.com/apache/ofbiz-framework/pull/1653/files)
- [Apache OFBiz: Download (24.09.08 release)](https://ofbiz.apache.org/download.html)
- [apache/ofbiz-framework VERSION file on tag release24.09.08](https://raw.githubusercontent.com/apache/ofbiz-framework/release24.09.08/VERSION)
