CVE-2026-57149 Overview
CVE-2026-57149 is a code injection vulnerability in plone.app.portlets, the portlet framework shipped with the Plone content management system. The Classic portlet (plone.app.portlets.portlets.classic) constructs a Template Attribute Language Expression Syntax (TALES) path expression from user-supplied template and macro fields. The path() helper then evaluates that value as a full TALES expression, allowing attacker-controlled input to escape simple path traversal and execute arbitrary code. Any authenticated user permitted to configure a Classic portlet — including regular users on their personal dashboard under the default role map — can trigger the flaw. Affected releases include plone.app.portlets 5.0.0 through the fixed versions 5.0.8, 6.0.4, and 7.0.2.
Critical Impact
Authenticated users with default dashboard permissions can achieve remote code execution in the Plone server process, escalating privileges across the web-user to server trust boundary.
Affected Products
- plone.app.portlets versions 5.0.0 through 5.0.7
- plone.app.portlets versions 6.0.0 through 6.0.3
- plone.app.portlets versions 7.0.0 through 7.0.1
Discovery Timeline
- 2026-09-22 - CVE-2026-57149 published to the National Vulnerability Database
- 2026-09-23 - Last updated in NVD database
Technical Details for CVE-2026-57149
Vulnerability Analysis
The Classic portlet lets an authenticated user specify a template name and optional macro name to render. Instead of treating these values as plain strings for a path lookup, the portlet composes them into a TALES path expression and hands the composite string to the TAL path() helper. TALES supports full expression evaluation, including Python expressions in some configurations, so the helper interprets attacker-controlled input as executable code rather than a static path.
This behavior maps to CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code (Eval Injection). Successful exploitation yields code execution in the context of the Plone process, granting the attacker access to filesystem operations, database credentials, and any secrets available to the Zope application server.
Root Cause
The Classic portlet treats user-supplied template and macro fields as trusted inputs to a TALES expression builder. Because TALES is an expression language rather than a path resolver, values that include expression prefixes or traversal syntax escape the intended path lookup. The absence of input validation and the choice to evaluate the composed string with path() rather than resolving it as a literal template reference are the root causes.
Attack Vector
Exploitation requires network access to the Plone site and an authenticated account with the plone.app.portlets.ManageOwnPortlets permission. Under the default role map, this permission is granted to standard users on their personal dashboards. The attacker adds or edits a Classic portlet and supplies a crafted TALES expression in the template or macro field. When the portlet renders, the expression executes in the server process. No user interaction beyond the attacker's own session is required, and the scope change reflects impact beyond the vulnerable component to the entire Plone deployment.
Refer to the GitHub Security Advisory GHSA-rr49-f9g6-c9r5 for authoritative technical details.
Detection Methods for CVE-2026-57149
Indicators of Compromise
- Portlet configuration records containing TALES expression prefixes such as python:, nocall:, or string: within Classic portlet template or macro fields.
- Unexpected child processes or outbound network connections originating from the Zope or Plone application server process.
- New or modified files under the Plone instance directory that do not correspond to a scheduled deployment.
- Audit log entries showing non-administrative users editing or creating Classic portlets outside normal usage patterns.
Detection Strategies
- Inspect the ZODB or portlet assignment storage for Classic portlet entries whose template or macro values contain characters or keywords beyond simple identifiers.
- Monitor Plone application logs for TAL or TALES traceback entries referencing path() evaluation errors, which may indicate exploitation attempts.
- Correlate portlet configuration changes with subsequent process, filesystem, or network anomalies on the hosting server.
Monitoring Recommendations
- Enable process and file integrity monitoring on hosts running Plone to surface unexpected child processes spawned by the application server.
- Ship Plone access and event logs to a centralized analytics platform and alert on portlet edit events performed by non-administrator roles.
- Track network egress from Plone servers and alert on connections to unknown external endpoints.
How to Mitigate CVE-2026-57149
Immediate Actions Required
- Upgrade plone.app.portlets to version 5.0.8, 6.0.4, or 7.0.2, matching the deployed major branch.
- Audit existing Classic portlet configurations for suspicious template or macro values and remove any that were not created by trusted administrators.
- Review the site's role map and revoke plone.app.portlets.ManageOwnPortlets from untrusted roles until patching is complete.
Patch Information
The Plone maintainers released fixes in plone.app.portlets 5.0.8, 6.0.4, and 7.0.2. Deploy the update that corresponds to your branch and restart the Zope or Plone process. Details are documented in the GitHub Security Advisory GHSA-rr49-f9g6-c9r5.
Workarounds
- Restrict portlet management by removing plone.app.portlets.ManageOwnPortlets from untrusted roles and limiting the Manage portlets permission to the Manager and Site Administrator roles.
- Unregister the Classic portlet by editing a portlets.xml in your own code where the portlet is not required.
- Neutralize the Classic portlet by customizing its template in the Zope Management Interface: navigate to portal_view_customizations, open classic.pt, click Customize, and replace the contents with <div>The classic portlet was disabled.</div>.
# Configuration example: pin the patched release in requirements or buildout
pip install 'plone.app.portlets>=7.0.2'
# For the 6.x branch
pip install 'plone.app.portlets>=6.0.4,<7.0.0'
# For the 5.x branch
pip install 'plone.app.portlets>=5.0.8,<6.0.0'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.