""" NeuroSploit v3 - XSS Context Analyzer Determines whether a payload reflected in HTML is in an executable position (auto-executing, interactive, or non-executable text content). Used by XSS testers and response verifier for context-aware validation. """ import re from typing import Dict, Optional # Auto-executing events (fire without user interaction) AUTO_FIRE_EVENTS = { "onload", "onerror", "onabort", "onbegin", "onend", "onanimationend", "onanimationstart", "ontransitionend", "onhashchange", "onpageshow", "onpopstate", "onresize", "onscroll", "onstorage", "onunload", "ontoggle", # when paired with
} # Interactive events (require user action) INTERACTIVE_EVENTS = { "onclick", "ondblclick", "onmousedown", "onmouseup", "onmouseover", "onmousemove", "onmouseout", "onmouseenter", "onmouseleave", "onkeypress", "onkeydown", "onkeyup", "onfocus", "onblur", "onchange", "onsubmit", "onreset", "onselect", "oninput", "oncontextmenu", "oncopy", "oncut", "onpaste", "ondrag", "ondrop", "onpointerdown", "onpointerup", "onpointerover", "onpointermove", "ontouchstart", "ontouchend", "ontouchmove", "onfocusin", "onfocusout", "onauxclick", "onsearch", } ALL_EVENTS = AUTO_FIRE_EVENTS | INTERACTIVE_EVENTS # Tags that auto-fire events AUTO_FIRE_TAGS = { "script": True, # auto-executes content "img": {"onerror"}, "video": {"onerror"}, "audio": {"onerror"}, "source": {"onerror"}, "object": {"onerror"}, "embed": {"onerror"}, "body": {"onload"}, "svg": {"onload"}, "math": set(), "input": {"onfocus"}, # with autofocus "select": {"onfocus"}, "textarea": {"onfocus"}, "details": {"ontoggle"}, # with open attribute } # Safe containers that suppress execution SAFE_CONTAINERS = {"textarea", "title", "noscript", "xmp", "plaintext", "listing"} # Pattern to find the innermost enclosing tag _RE_BEFORE_TAG = re.compile(r'<(\w+)(?:\s[^>]*)?>(?=[^<]*$)', re.IGNORECASE) _RE_OPEN_SCRIPT = re.compile(r']*>', re.IGNORECASE) _RE_CLOSE_SCRIPT = re.compile(r')', re.DOTALL) _RE_STYLE_OPEN = re.compile(r']*>', re.IGNORECASE) _RE_STYLE_CLOSE = re.compile(r' Dict: """ Determine whether a payload reflected in HTML is in an executable position. Returns: { "executable": bool, # True if payload can auto-execute (no user action) "interactive": bool, # True if payload executes WITH user interaction "context": str, # Context identifier "confidence": float, # 0.0 - 1.0 "detail": str, # Human-readable explanation } """ result = { "executable": False, "interactive": False, "context": "not_found", "confidence": 0.0, "detail": "Payload not found in response", } if not html_body or not payload: return result if payload_lower is None: payload_lower = payload.lower() body_lower = html_body.lower() # Find payload position (try exact first, then case-insensitive) pos = html_body.find(payload) if pos == -1: pos = body_lower.find(payload_lower) if pos == -1: return result # Extract surrounding context before_start = max(0, pos - 300) after_end = min(len(html_body), pos + len(payload) + 150) before = html_body[before_start:pos] after = html_body[pos + len(payload):after_end] before_lower = before.lower() after_lower = after.lower() # Check for HTML encoding of the payload encoded_payload = payload.replace("<", "<").replace(">", ">") if encoded_payload != payload and encoded_payload in html_body: # The payload appears HTML-encoded result.update({ "context": "encoded", "confidence": 0.1, "detail": f"Payload appears HTML-encoded (</>)", }) return result # --- Check 1: Inside HTML comment --- if "" not in before[before.rfind("