/claim #5838
Adds pkg/fuzz/analyzers/xss/ — a standalone XSS context analyzer that determines where in an HTML document a reflected fuzz marker lands, then returns context-appropriate exploit payloads with confidence scores.
Fixes the javascript: URI misclassification described in #7086.
The fuzzing engine finds reflections but has no way to tell where in the HTML the value lands. Without context, you either spray every XSS payload everywhere (slow, noisy, false-positive-heavy) or miss valid injection points entirely.
AnalyzeReflectionContext(responseBody, marker string) XSSResult
Uses golang.org/x/net/html tokenizer (already in go.mod) to walk the HTML token stream. Returns a full XSSResult with:
AnalyzeAllReflections scans the entire document for all occurrences; AnalyzeReflectionContext returns the most exploitable one.
Implements the analyzers.Analyzer interface (registered as "xss_context") so it can be referenced in template YAML.
| Context | Example |
|---|---|
HTMLBody |
<p>MARKER</p> |
Comment |
<!-- MARKER --> |
AttributeDouble |
<tag attr="MARKER"> |
AttributeSingle |
<tag attr='MARKER'> |
AttributeUnquoted |
<tag attr=MARKER> |
AttributeURL |
<a href="MARKER"> |
AttributeEvent |
<div onclick="MARKER"> |
AttributeStyle |
<div style="MARKER"> |
Script |
<script>MARKER</script> or executable javascript: URI |
ScriptData |
<script type="application/json">MARKER |
Style |
<style>MARKER { }\</style> |
JSON |
{"key": "MARKER"} inside a script block |
Template |
\hello ${MARKER}`` in a script block |
CDATA |
<![CDATA[MARKER]]> |
SrcDoc |
<iframe srcdoc="MARKER"> |
Unknown |
marker not found or context unparseable |
javascript: URI executability is tag-aware (fixes #7086):
<a href="javascript:"> → ContextScript ✓ (executes)<iframe src="javascript:"> → ContextScript ✓ (executes)<img src="javascript:"> → ContextAttributeURL ✓ (does NOT execute)<script src="javascript:"> → ContextAttributeURL ✓ (does NOT execute)First type attribute wins on <script> (HTML5 spec):
<script type="application/json" type="text/javascript"> → ContextScriptData (non-executable)TagAttr() single-pass — the tokenizer’s attribute iterator is forward-only. Scanning in one pass prevents silent attribute dropping (e.g. <script src="MARKER"> would be missed in a two-pass approach).
Quote style detection — the raw HTML source is probed to determine the actual delimiter (", ', or unquoted) so breakout sequences are correct.
$ go test ./pkg/fuzz/analyzers/xss/... -v
...
PASS
ok github.com/projectdiscovery/nuclei/v3/pkg/fuzz/analyzers/xss
Covers:
type attrs on <script>Benchmarks (Apple M4):
BenchmarkAnalyzeReflectionContext_HTMLBody 898772 1267 ns/op 4896 B/op 21 allocs/op
BenchmarkAnalyzeReflectionContext_LargeDocument 9140 131626 ns/op 44468 B/op 1815 allocs/op
BenchmarkAnalyzeAllReflections 677701 2145 ns/op 6208 B/op 32 allocs/op
dev branchgo build ./pkg/fuzz/... succeedsanalyzers.Analyzer interfacejavascript: URI misclassification (#7086) fixed with tag-aware sink mapNew Features
Tests
CharlesWong
@CharlesWong
ProjectDiscovery
@projectdiscovery