CVE-2026-16337
dotCMS vulnerability analysis and mitigation

Overview

CVE-2026-16337 is a critical improper authorization vulnerability in dotCMS affecting the ToolGroupResource and RoleAjax REST/DWR endpoints. It allows any low-privileged authenticated backend user to self-assign the administrative layout and self-grant the CMS Administrator role, ultimately enabling remote code execution (RCE) via a crafted OSGi bundle upload. All platforms running dotCMS versions 21.02 through 26.06.22-03 are affected, including all LTS lines (23.10, 24.04, 24.12, 25.07). The vulnerability was disclosed on July 20, 2026, with a patch merged on July 15, 2026. It carries a CVSS v4.0 base score of 9.4 (Critical) (GitHub Advisory, dotCMS PR #36344).

Technical details

The vulnerability is classified as CWE-269 (Improper Privilege Management) and stems from two missing authorization checks that form a privilege-escalation chain. First, the PUT /api/v1/toolgroups/{id}/_addtouser endpoint in ToolGroupResource.java lacked any admin check, allowing any authenticated backend user to self-assign the administrative Settings layout (which contains the roles portlet). Second, the POST /dwr/call/plaincall/RoleAjax.addUserToRole.dwr endpoint in RoleAjax.java only verified portlet-level access — not actual role membership — meaning a user who gained roles-portlet access via step one could then grant themselves the CMS Administrator role. With CMS Administrator privileges, the attacker can upload a malicious OSGi bundle whose BundleActivator executes arbitrary OS shell commands. The ToolGroupResource gap was introduced in December 2020 (v21.02) and the RoleAjax portlet-only gate dates to March 2012; a partial mitigation was added in v25.11.07-1 but was insufficient to break the full chain (dotCMS PR #36344, GitHub Advisory).

Impact

Successful exploitation results in full compromise of the dotCMS server, with high impact to confidentiality, integrity, and availability of both the vulnerable system and any subsequent systems it can reach. An attacker achieving RCE via the malicious OSGi bundle executes arbitrary OS commands as the dotCMS service account, enabling data exfiltration, credential theft, installation of backdoors, and lateral movement within the network. All authenticated backend users — including those with minimal privileges such as content editors — represent a potential attack surface (GitHub Advisory, dotCMS PR #36344).

Exploitability

As of the disclosure date (July 20, 2026), there is no public proof-of-concept exploit and no evidence of in-the-wild exploitation. The NVD SSVC assessment confirms exploitation status as "none" and the attack is not automatable, as it requires an authenticated backend user account. The EPSS score is approximately 0.4% (33rd percentile), indicating a relatively low near-term exploitation probability. The vulnerability is not currently listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. A researcher-reported PoC script was referenced in the fix PR but has not been publicly released (GitHub Advisory, dotCMS PR #36344).

Exploitation steps

  1. Reconnaissance: Identify a dotCMS instance running versions 21.02 through 26.06.22-03. Obtain or create a low-privileged backend user account (e.g., a content editor account).
  2. Self-assign admin layout: Authenticate to the dotCMS backend and send a PUT request to /api/v1/toolgroups/{admin_settings_layout_id}/_addtouser with the attacker's session credentials. Due to the missing admin check, the server assigns the administrative Settings layout (containing the roles portlet) to the attacker's account.
  3. Self-grant CMS Administrator role: With the roles portlet now accessible, send a POST request to /dwr/call/plaincall/RoleAjax.addUserToRole.dwr specifying the CMS Administrator role ID and the attacker's user ID. The endpoint only checks portlet access (satisfied in step 2), not actual role membership, so the role grant succeeds.
  4. Craft malicious OSGi bundle: Create a Java OSGi bundle with a BundleActivator class whose start() method executes arbitrary OS commands (e.g., a reverse shell or data exfiltration command) via Runtime.getRuntime().exec().
  5. Upload and activate bundle: Using the newly acquired CMS Administrator session, navigate to the OSGi bundle upload interface and upload the crafted bundle. Upon activation, the BundleActivator executes the embedded shell commands on the server as the dotCMS service account, achieving RCE (dotCMS PR #36344).

Indicators of compromise

  • Network: Unexpected PUT requests to /api/v1/toolgroups/{layoutId}/_addtouser from non-administrative user sessions; POST requests to /dwr/call/plaincall/RoleAjax.addUserToRole.dwr from accounts that do not hold the CMS Administrator role; outbound connections from the dotCMS server process to unknown external IPs.
  • Logs: dotCMS access logs showing a low-privileged user accessing the Settings layout or roles portlet; audit logs recording a role change granting CMS Administrator to a non-admin user; SecurityLogger entries (post-patch) indicating unauthorized role-assignment attempts.
  • File System: Newly uploaded OSGi bundle files (.jar) in the dotCMS OSGi deploy directory containing unexpected BundleActivator classes; new files created by the dotCMS service account in unusual directories (e.g., web shells, scripts).
  • Process: Unexpected child processes spawned by the dotCMS JVM process (e.g., /bin/sh, cmd.exe, curl, wget, python, nc); unusual cron jobs or scheduled tasks created under the dotCMS service account (dotCMS PR #36344).

Mitigation and workarounds

The fix was merged in dotCMS PR #36344 on July 15, 2026, and published as a CVE on July 20, 2026. Organizations should update dotCMS to any release built after the merge of PR #36344 (versions after 26.06.22-03). As interim workarounds: restrict backend user account creation and access to only essential personnel; implement network-level controls to limit access to the dotCMS admin backend; and monitor or disable OSGi bundle upload functionality for non-administrative users. Additionally, audit existing backend user accounts for unexpected CMS Administrator role assignments (dotCMS PR #36344, GitHub Advisory).

Community reactions

The vulnerability was reported to dotCMS via responsible disclosure and tracked internally as dotCMS/private-issues#642. The fix was developed collaboratively using AI-assisted code review (Claude) and underwent a multi-round red team review process before merge. No significant public media coverage or notable external researcher commentary has been identified at this time (dotCMS PR #36344).

Additional resources


SourceThis report was generated using AI

Related dotCMS vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-8054CRITICAL10
  • dotCMS logodotCMS
  • cpe:2.3:a:dotcms:dotcms
NoYesMay 27, 2026
CVE-2026-16337CRITICAL9.4
  • dotCMS logodotCMS
  • cpe:2.3:a:dotcms:dotcms
NoYesJul 20, 2026
CVE-2025-11165CRITICAL9.4
  • dotCMS logodotCMS
  • cpe:2.3:a:dotcms:dotcms
NoYesFeb 24, 2026
CVE-2024-3938MEDIUM6.1
  • dotCMS logodotCMS
  • cpe:2.3:a:dotcms:dotcms
NoYesJul 25, 2024
CVE-2024-3165MEDIUM4.5
  • dotCMS logodotCMS
  • cpe:2.3:a:dotcms:dotcms
NoYesApr 01, 2024

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management