Pimcore 11.4.2 - Stored cross site scripting

Exploit Author: maeitsec Analysis Author: www.bubbleslearn.ir Category: WebApps Language: PHP Published Date: 2025-04-14
# Exploit Title: Authenticated Stored Cross-Site Scripting (XSS) Via Search
Document
# Google Dork: N/A
# Date: 1/28/2025
# Exploit Author: maeitsec
# Vendor Homepage: https://pimcore.com/
# Software Link: https://github.com/pimcore/pimcore
# Version: Pimcore 10.5.x (prior to 10.5.21) and 11.x (prior to 11.1.1)
# Tested on: Pimcore 10.5.20 on Ubuntu 20.04
# CVE:  CVE-2024-11954

---

### Description:
A stored Cross-Site Scripting (XSS) vulnerability exists in Pimcore's Data
Object Classification Store functionality. The vulnerability arises due to
insufficient input sanitization, allowing an authenticated attacker with
access to the classification store to inject malicious JavaScript code.
This code is then executed in the context of other users' browsers when
they view the affected data.

### Proof of Concept (PoC):
1. Log in to the Pimcore backend as a user with access to the Data Object
Classification Store.
2. Navigate to the Classification Store and create or edit a key.
3. Inject the following payload into the key value:
   ```html
   <script>alert('XSS')</script>
4. Save the file and view it in the frontend or backend. The JavaScript
alert will execute, demonstrating the vulnerability.


Pimcore Stored Cross‑Site Scripting (XSS) — analysis, impact, and remediation

This article explains a stored Cross‑Site Scripting (XSS) issue associated with Pimcore's Data Object Classification Store (reported as CVE‑2024‑11954). It covers how the vulnerability works at a high level, who is affected, detection and remediation strategies, and secure coding practices to prevent recurrence. The emphasis is on defensive, actionable guidance for administrators and developers.

Summary

A stored (persistent) XSS vulnerability was identified in Pimcore’s classification store handling where unsanitized data entered into classification keys/values could be persisted and later rendered into pages or backend views without appropriate output encoding. An authenticated user with access to the classification store could add content that executes JavaScript in other users’ browsers when that content is rendered.

Affected versions and CVE

  • CVE: CVE‑2024‑11954
  • Reported affected series: Pimcore 10.5.x (prior to 10.5.21) and 11.x (prior to 11.1.1) — verify vendor advisories for exact fixed releases.
  • If you run any version older than the fixed releases above, treat the instance as potentially vulnerable until patched.

Why this is important (Impact)

  • Stored XSS enables execution of arbitrary JavaScript in the context of the target application domain.
  • Consequences include session token theft, forced actions via Cross‑Site Request Forgery (CSRF) in some contexts, persistent defacement, or delivery of secondary payloads.
  • Exploitation typically requires an authenticated user with permissions to edit classification store entries, so the attacker’s risk model is scoped by access controls — but many environments grant broad editorial/admin access, increasing risk.

Technical root cause (high level)

The core problem is insufficient output encoding/sanitization when rendering user‑controlled classification data. Data that can contain markup is stored and later injected into HTML contexts without being escaped or filtered for safe content. When user‑supplied data is included in HTML without proper context‑aware encoding, scripts (or other active content) can run in the victim’s browser.

Safe demonstration (conceptual, non‑exploitative)

To assess if your instance is affected without weaponizing the vulnerability, perform controlled, defensive checks in a non‑production environment. Rather than injecting active script, insert a distinct benign sentinel string (for example: CLASSIFICATION_TEST_2025) and verify where it appears when rendered. This helps find rendering paths that do not escape stored values without introducing executable code.

Detection and hunting guidance

  • Search for unescaped characters or suspicious text patterns in stored classification values. For example, look for values containing angle brackets or attributes that may lead to rendering as HTML.
  • Scan rendered pages (frontend and backend) for occurrences of data originating from the classification store to confirm whether values are being HTML‑escaped.
  • Use automated scanners that support authenticated crawling of the backend UI to flag reflected or stored injection points; run these in test environments only.
  • Review server and application logs for unusual requests or for edits to classification store entries outside normal operational patterns. Enable audit logging for changes to classification data.

Short‑term mitigations

  • Limit access: Restrict who can create or edit classification store entries. Apply the principle of least privilege to editorial/admin accounts.
  • Monitoring: Add alerting on changes to classification store data and on rendering errors that might indicate injected content.
  • Content Security Policy (CSP): Where practical, introduce a strong CSP to reduce the impact of injected scripts (e.g., disallow inline scripts and only allow scripts from trusted sources). CSP is defense‑in‑depth and does not replace proper escaping.
  • Escape user content where you can’t immediately patch: Ensure any templates that print classification values use context‑aware escaping/encoding (see code examples below).

Permanent fix — patch and upgrade

The definitive remediation is to apply vendor patches. Check Pimcore’s official security advisories and upgrade to the fixed release(s) specified for CVE‑2024‑11954 (or later, ideally the latest stable Pimcore release). If you cannot immediately upgrade, apply temporary controls described above and plan prioritized upgrade work.

Secure coding and mitigation examples

Below are defensive code patterns and configuration approaches to prevent stored XSS in web applications like Pimcore (Symfony/Twig/PHP stack). These examples show how to encode output and use HTML sanitizers safely. Use them as guidelines — adapt to your app’s templating and rendering contexts.

1) Twig — always escape output by default

{{ classificationValue|e('html') }}

Explanation: In Twig templates the escape filter (|e) with the 'html' strategy encodes special characters so they are rendered as text rather than interpreted as HTML. Ensure autoescape is enabled for templates (Twig’s autoescape should be on for HTML templates).

2) PHP — HTML encode before output

// Safe output in PHP
echo htmlspecialchars($classificationValue, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

Explanation: htmlspecialchars converts characters like <, >, ", and ' into HTML entities, preventing browsers from interpreting them as active markup. ENT_SUBSTITUTE ensures invalid UTF‑8 sequences don’t cause unexpected output.

3) When HTML is required — use a whitelist HTML sanitizer

// Example using HTML Purifier (recommended for controlled HTML input)
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.Allowed', 'p,b,strong,i,em,a[href|title|rel],ul,ol,li,br'); // choose allowed tags/attributes
$purifier = new HTMLPurifier($config);
$cleanHtml = $purifier->purify($userProvidedHtml);
echo $cleanHtml;

Explanation: If users are allowed to submit rich text containing HTML, sanitize with a robust library (HTMLPurifier) using a whitelist of allowed tags and attributes. Do not rely on naive strip_tags approaches because they can be bypassed.

4) CSP header example (defense‑in‑depth)

// Example header — adapt to your environment
header("Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self';");

Explanation: A strict Content Security Policy limits where scripts and other resources can be loaded from. It reduces the impact of successful XSS by preventing execution of inline or external scripts not allowed by the policy. CSP should accompany secure escaping and not replace it.

5) Server-side validation and role checks

// Pseudocode — validate on input and check permissions
if (!currentUser->hasRole('classification_editor')) {
    throw new AccessDeniedException();
}
$sanitizedInput = trim($inputValue);
if (strlen($sanitizedInput) === 0) { /* handle invalid */ }
storeClassificationValue($key, $sanitizedInput);

Explanation: Combine strict authorization checks with basic input validation. Even non‑trusted admin input should be validated and then safely encoded on output.

Recommended remediation checklist

  • Immediately verify your Pimcore version and apply vendor patches or upgrade to a fixed version.
  • Restrict write access to classification stores to the smallest set of users required.
  • Audit templates and rendering code for any place classification values are printed; apply context‑aware escaping.
  • Introduce or strengthen CSP headers and other HTTP security headers (X-Content-Type-Options, X-Frame-Options, Referrer‑Policy, etc.).
  • Sanitize rich text with a whitelist sanitizer when HTML is allowed.
  • Enable application audit logging for changes to classification entries and monitor those logs for suspicious updates.
  • Perform authenticated security testing (in staging) after remediation to validate fixes.

Detection queries and monitoring ideas (defensive)

  • Search the classification store export/DB table for values containing characters indicative of markup (for example, angle brackets). Use these searches only in a controlled, audited process.
  • Monitor for unexpected client‑side errors (JavaScript exceptions) in Sentry or similar that correlate with user roles or classification pages.
  • Set up alerts for changes to classification store rows by unusual users or at unusual times.

Final notes and best practices

Stored XSS is common when stored user input is later rendered into HTML without appropriate encoding. The most reliable defenses are:

  • Patching vendor fixes promptly.
  • Encoding at the point of output (context‑aware escaping).
  • Validating and sanitizing input where appropriate.
  • Least privilege for data editing roles, combined with strong monitoring and CSP.

For exact remediation steps and version guidance, consult Pimcore’s official security advisory and release notes, then test patches in a staging environment before deploying to production.