Implements a new xss_context analyzer for the fuzzing engine that classifies reflected XSS injection points by their HTML context and determines exploitability. This closes #5838.
[XSS_CANARY] in payloads with a canary string containing HTML/JS-significant probe characters: <>'" and backtickhtml-body — between HTML tags (<div>VALUE</div>)html-attr-double-quoted — inside "..." attributehtml-attr-single-quoted — inside '...' attributehtml-attr-unquoted — unquoted attribute valuescript-block — inside <script> outside stringsscript-string-double — inside JS "..." stringscript-string-single — inside JS '...' stringscript-template — inside JS template literalhtml-comment — inside <!-- ... -->style-block — inside <style> tagurl-attribute — in href/src/action attributes<> for html-body, " for double-quoted attributes)pkg/fuzz/analyzers/xss/ with three files:
analyzer.go — implements analyzers.Analyzer interface, registered as xss_contextcontext.go — HTML context classification engine using heuristic parsingcontext_test.go — 23 comprehensive testspkg/fuzz/analyzers/analyzers.go — added ResponseBody and ResponseHeaders to Optionspkg/protocols/http/request.go — passes response body/headers to analyzerpkg/protocols/http/http.go — blank import for auto-registrationhtml.Tokenizer for context classification because the canary itself contains HTML-breaking characters (<>'") that would cause a standard tokenizer to misparse the documenttime_delay analyzerResponseBody is provided)http:
- method: GET
path:
- "{{BaseURL}}/search?q=[XSS_CANARY]"
fuzzing:
- type: query
part: value
mode: single
fuzz:
- "[XSS_CANARY]"
analyzer:
name: xss_context
All 23 tests pass with go vet clean:
$ go vet ./pkg/fuzz/analyzers/xss/...
$ go test ./pkg/fuzz/analyzers/xss/... -v -count=1
=== RUN TestClassifyReflections_HTMLBody
--- PASS: TestClassifyReflections_HTMLBody (0.00s)
=== RUN TestClassifyReflections_AttrDoubleQuoted
--- PASS: TestClassifyReflections_AttrDoubleQuoted (0.00s)
=== RUN TestClassifyReflections_AttrSingleQuoted
--- PASS: TestClassifyReflections_AttrSingleQuoted (0.00s)
=== RUN TestClassifyReflections_ScriptBlock
--- PASS: TestClassifyReflections_ScriptBlock (0.00s)
=== RUN TestClassifyReflections_ScriptStringDouble
--- PASS: TestClassifyReflections_ScriptStringDouble (0.00s)
=== RUN TestClassifyReflections_ScriptStringSingle
--- PASS: TestClassifyReflections_ScriptStringSingle (0.00s)
=== RUN TestClassifyReflections_ScriptTemplateLiteral
--- PASS: TestClassifyReflections_ScriptTemplateLiteral (0.00s)
=== RUN TestClassifyReflections_HTMLComment
--- PASS: TestClassifyReflections_HTMLComment (0.00s)
=== RUN TestClassifyReflections_StyleBlock
--- PASS: TestClassifyReflections_StyleBlock (0.00s)
=== RUN TestClassifyReflections_URLAttribute
--- PASS: TestClassifyReflections_URLAttribute (0.00s)
=== RUN TestClassifyReflections_MultipleReflections
--- PASS: TestClassifyReflections_MultipleReflections (0.00s)
=== RUN TestClassifyReflections_NoReflection
--- PASS: TestClassifyReflections_NoReflection (0.00s)
=== RUN TestClassifyReflections_EmptyInputs
--- PASS: TestClassifyReflections_EmptyInputs (0.00s)
=== RUN TestClassifyReflections_CaseInsensitive
--- PASS: TestClassifyReflections_CaseInsensitive (0.00s)
=== RUN TestIsExploitable_HTMLBody
--- PASS: TestIsExploitable_HTMLBody (0.00s)
=== RUN TestIsExploitable_HTMLBodyEncoded
--- PASS: TestIsExploitable_HTMLBodyEncoded (0.00s)
=== RUN TestIsExploitable_AttrDoubleQuoted
--- PASS: TestIsExploitable_AttrDoubleQuoted (0.00s)
=== RUN TestIsExploitable_ScriptBlock
--- PASS: TestIsExploitable_ScriptBlock (0.00s)
=== RUN TestBuildCanary
--- PASS: TestBuildCanary (0.00s)
=== RUN TestBuildCanary_CustomPrefix
--- PASS: TestBuildCanary_CustomPrefix (0.00s)
=== RUN TestContextString
--- PASS: TestContextString (0.00s)
=== RUN TestClassifyJSContext
--- PASS: TestClassifyJSContext (0.00s)
=== RUN TestFormatFindings
--- PASS: TestFormatFindings (0.00s)
PASS
ok github.com/projectdiscovery/nuclei/v3/pkg/fuzz/analyzers/xss 0.087s
/claim #5838
Nenad Ilic
@nenadilic84
ProjectDiscovery
@projectdiscovery