Back to Blog
vulnerability research

CVE-2023-3479: Reflected XSS in HestiaCP

January 15, 2024
8 min read
By Vikas Gupta
Share:
CVEXSSHestiaCPSecurity Research

CVE-2023-3479: Reflected XSS in HestiaCP — How a Simple Script Led to a CVE

Introduction

During my security research, I discovered a reflected Cross-Site Scripting (XSS) vulnerability in HestiaCP - a popular open-source hosting control panel. This issue was later assigned CVE-2023-3479 and documented in the National Vulnerability Database.

Interestingly, the vulnerability was not found through traditional fuzzing or manual pentesting, but through a simple idea:

Extract all reachable paths from the codebase → request them → detect unparsed variables like $_GET & $_POST.

This combination of static + dynamic analysis surfaced an endpoint that contained a reflected XSS.


High-Level Flow of My Detection Process

+---------------------------+
|   Download Codebase       |
+-------------+-------------+
              |
              v
+---------------------------+
|  Enumerate All File Paths |
+-------------+-------------+
              |
              v
+-------------------------------------+
| Filter Only PHP / Processable Files |
+-------------+-----------------------+
              |
              v
+---------------------------+
|  Build URLs for Each Path |
+-------------+-------------+
              |
              v
+---------------------------+
| Send HTTP GET Requests    |
+-------------+-------------+
              |
              v
+-----------------------------------+
| If HTTP 200 → Inspect File for    |
| $_GET / $_POST Usage              |
+-------------+---------------------+
              |
              v
+---------------------------+
| Manual Verification (XSS) |
+---------------------------+

How I Automated the Discovery

I wanted a lightweight way to:

  1. Extract every PHP file and path from the codebase
  2. Request each one
  3. Detect unvalidated variables inside the file
  4. Prioritize only URLs returning HTTP 200

Combining these steps exposes endpoints that contain:

  • reachable URLs
  • unvalidated input handlers

Perfect targets for XSS and injection research.


The Script That Found the XSS

https://github.com/iamxhunt3r/smartfuzz

<?php
stream_context_set_default( [
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
]);
function checkUrl($url) {
$headers = get_headers($url);
return strpos($headers[0], '200') !== false;
}
function checkForUnparsedVariables($filename) {
$content = file_get_contents($filename);
if (strpos($content, '$_GET') !== false) {
echo "Unparsed \$_GET variables found in: $filename\n";
}
if (strpos($content, '$_POST') !== false) {
echo "Unparsed \$_POST variables found in: $filename\n";
}
}
if ($argc < 3) {
echo "Usage: php research_xss_fuzz.php <file_directory> <hostname>\n";
exit(1);
}
$fileDirectory = $argv[1];
$hostname = $argv[2];
function getFilesInDirectory($dir) {
global $fileDirectory;
$fileList = [];
$files = scandir($dir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$fullPath = $dir . DIRECTORY_SEPARATOR . $file;
if (is_dir($fullPath)) {
$fileList = array_merge($fileList, getFilesInDirectory($fullPath));
} else {
$ext = pathinfo($fullPath, PATHINFO_EXTENSION);
if (!in_array($ext, ['png','jpg','jpeg','gif','woff2','eot','svg','ttf','woff','css','js','mo','pot'])) {
$fileList[] = str_replace($fileDirectory . '/', "", $fullPath);
}
}
}
return $fileList;
}
$files = getFilesInDirectory($fileDirectory);
foreach ($files as $file) {
$fullFilePath = $fileDirectory . DIRECTORY_SEPARATOR . $file;
$url = "$hostname/$file";
if (checkUrl($url)) {
echo "HTTP 200 response for: $url\n";
checkForUnparsedVariables($fullFilePath);
}
}
?>

Running the script:

php research_xss_fuzz.php /path/to/hestiacp/ http://target.com

This revealed multiple valid paths and one particularly interesting endpoint returning:

  • HTTP 200
  • Unvalidated $_GET variable
  • Reflecting input directly into output

Which eventually led to the XSS.


Technical Breakdown of the Vulnerability

CVE ID: CVE-2023-3479
Type: Reflected Cross-Site Scripting
CVSS: 6.1
Component: HestiaCP web interface

The vulnerable parameter reflected user input without:

  • Validation
  • Encoding
  • Sanitization

Example payload:

<script>alert('XSS')</script>

Successfully executed in the admin interface.


Attack Vector Diagram

Attacker
   |
   | 1. Sends malicious URL
   v
Admin clicks URL
   |
   | 2. Payload reflected without sanitization
   v
Browser executes JS
   |
   | 3. Attacker gains control
   v
Account Compromise

Impact

An attacker could:

  • Steal admin session tokens
  • Execute privileged actions
  • Redirect or manipulate UI
  • Compromise the entire hosting panel

Remediation

The HestiaCP team fixed the issue by:

  1. Input validation
  2. Output sanitization
  3. Encoding reflected parameters
  4. Strengthening CSP headers

Timeline

  • Discovery: March 2023
  • Vendor Notified: March 2023
  • CVE Assigned: June 2023
  • Public Disclosure: July 2023

Thoughts on Automated Detection

While modern SAST tools and AI can detect unsanitized variables, my hybrid approach (static extraction + dynamic requests) still finds:

  • Legacy code paths
  • Hidden debug endpoints
  • Panels with inconsistent sanitization

This simple script continues to have potential for expanding into a lightweight XSS research toolkit.


Conclusion

CVE-2023-3479 demonstrates how even minimal automation can reveal impactful vulnerabilities. The insight here is not the complexity of the bug, but the effectiveness of blending static and dynamic analysis using simple tooling.


References

  • https://nvd.nist.gov/vuln/detail/CVE-2023-3479
  • https://github.com/iamxhunt3r/smartfuzz
  • https://hestiacp.com
  • https://owasp.org/www-project-cheat-sheets/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html

This blog post is for educational purposes and demonstrates the importance of responsible vulnerability disclosure.

Written by Vikas Gupta

Security Engineer & Full-Stack Developer