Summary
A code injection vulnerability in Plone's Classic portlet allows an authenticated user who can configure that portlet to cause a crafted template or macro value to be evaluated as executable TALES code. Successful exploitation may result in arbitrary code execution within the Plone server process and privilege escalation from a web user to the server-side application context.
Affected context
The issue occurs in the Classic portlet when user-supplied template or macro fields are incorporated into a TALES path expression and evaluated by the TAL path() helper. It is relevant to Plone deployments using affected plone.app.portlets releases where authenticated users, including potentially regular users on personal dashboards, can add or edit Classic portlets.
Exploit preconditions
- Attack surface: The Classic portlet configuration interface
- Required access: An authenticated account with permission to add or edit a Classic portlet
- Trigger point: Rendering or processing the configured template or macro value
- Why exploitation is possible: User-controlled content is interpreted as a complete TALES expression rather than being constrained to a safe resource path
Why this happens
The vulnerability results from constructing a dynamic TALES expression from user-controlled template or macro values and passing it to an evaluator that supports executable expression semantics. This insecure pattern crosses the boundary between data and code, allowing specially crafted input to escape intended path resolution and invoke server-side behavior. It maps to CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code.
Potential impact
- An attacker may execute arbitrary code in the Plone process context.
- An attacker could access or modify application data available to that process.
- The vulnerability may enable privilege escalation across the web-user and server-process trust boundary.
- An attacker could compromise site configuration or use the process context for further internal access.
General mitigation guidance
Mitigation generally focuses on preventing user-controlled values from reaching dynamic expression evaluators and reducing access to the affected configuration surface.
Defensive patterns include:
- Treating template, macro, and path fields as data rather than executable expressions.
- Using fixed, allowlisted template references and non-evaluating lookup mechanisms.
- Restricting portlet-management permissions to trusted administrative roles.
- Removing or unregistering the Classic portlet when it is not required.
- Applying least privilege to the Plone process and its service account.
- Keeping security-sensitive configuration and customization interfaces inaccessible to untrusted users.
How teams detect issues like this
Organizations can look for this class of issue through:
- Static analysis that flags dynamic construction of TALES or other template-language expressions from request or form data.
- Code review checks for user-controlled input passed to expression evaluators, template engines, or dynamic path helpers.
- Testing that verifies template and macro fields accept only predefined, non-executable identifiers.
- Monitoring changes to Classic portlet configurations and unexpected server-side process behavior.
- Policy enforcement that limits portlet-management permissions and prevents untrusted users from customizing executable templates.
Automated security review tools may help identify data-to-code flows involving template evaluation APIs.

