Skip to content

feat(fuzz): Add XSS Context Analyzer (Closes #5838)#7038

Open
sonumishrAA wants to merge 3 commits intoprojectdiscovery:devfrom
sonumishrAA:feat-xss-analyzer
Open

feat(fuzz): Add XSS Context Analyzer (Closes #5838)#7038
sonumishrAA wants to merge 3 commits intoprojectdiscovery:devfrom
sonumishrAA:feat-xss-analyzer

Conversation

@sonumishrAA
Copy link

@sonumishrAA sonumishrAA commented Feb 25, 2026

/claim #5838

Proposed Changes

I have added an intelligent XSS Context Analyzer in pkg/fuzz/analyzers/xss.
It uses golang.org/x/net/html for proper HTML tokenization, allowing it to accurately detect reflection in:

  • HTML Text
  • Script Blocks
  • Attribute Values & Names
  • HTML Comments

Proof

Verified with 6 local unit tests. All tests passed.
Output:
--- PASS: TestDetermineContext (0.00s)
--- PASS: TestDetermineContext/HTML_Text_Context (0.00s)
--- PASS: TestDetermineContext/Script_Block_Context (0.00s)
--- PASS: TestDetermineContext/Attribute_Value_Context (0.00s)
--- PASS: TestDetermineContext/Attribute_Name_Context (0.00s)
--- PASS: TestDetermineContext/HTML_Comment_Context (0.00s)

Checklist

  • PR created against the correct branch (dev)
  • Tests added to prove the feature works

Summary by CodeRabbit

  • New Features

    • Added an XSS context analyzer that detects payload reflection in HTTP responses and reports the precise reflection context (HTML text, attribute name, attribute value, script block, HTML comment, or unknown).
  • Tests

    • Added tests validating context detection across varied HTML constructs to ensure accurate classification of reflected payloads.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 022d73a and 4526511.

📒 Files selected for processing (1)
  • pkg/fuzz/analyzers/xss/analyzer_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/fuzz/analyzers/xss/analyzer_test.go

Walkthrough

Adds an XSS context analyzer that sends fuzzed HTTP requests, detects payload reflections in responses, and classifies the reflection context (HTML text, attribute name/value, script block, comment, or unknown) using HTML tokenization. Includes unit tests for the context detection logic.

Changes

Cohort / File(s) Summary
XSS Context Analyzer
pkg/fuzz/analyzers/xss/analyzer.go
New public Analyzer type implementing analyzers.Analyzer; Name(), ApplyInitialTransformation(), and Analyze() methods added. Analyze() rebuilds and sends requests, reads responses, searches for payload reflection, and calls determineContext() to classify the reflection. Registers as xss_context.
XSS Context Analyzer Tests
pkg/fuzz/analyzers/xss/analyzer_test.go
New unit tests for determineContext() covering HTML Text, Script Block, Attribute Value, Attribute Name, HTML Comment, and Unknown contexts using a fixed payload and multiple HTML snippets.

Sequence Diagram

sequenceDiagram
    participant Analyzer as XSS Analyzer
    participant HTTPClient as HTTP Client
    participant Server as Target Server
    participant Parser as HTML Tokenizer

    Analyzer->>HTTPClient: Build fuzzed request (inject payload)
    HTTPClient->>Server: Send HTTP request
    Server-->>HTTPClient: Return HTTP response
    HTTPClient-->>Analyzer: Deliver response body

    alt payload found in body
        Analyzer->>Parser: Tokenize HTML body
        Parser-->>Analyzer: Return tokens
        Analyzer->>Analyzer: determineContext() -> classify reflection
        Analyzer-->>Analyzer: Return (true, context)
    else payload not found
        Analyzer-->>Analyzer: Return (false, "")
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hid a payload, quick and neat,
Between tags and quotes it made retreat,
Tokens told me where it lay,
In text, script, or attrs astray,
A hopping win — XSS found! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding an XSS Context Analyzer. It is concise, specific, and directly related to the primary modification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/fuzz/analyzers/xss/analyzer.go (1)

35-36: Guard options.HttpClient before calling Do.

A nil HttpClient would panic at Line [44]. Add a defensive guard in the upfront validation block.

🛡️ Suggested hardening
-	if options == nil || options.FuzzGenerated.Component == nil {
+	if options == nil || options.HttpClient == nil || options.FuzzGenerated.Component == nil {
 		return false, "", nil
 	}

Also applies to: 44-45

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/fuzz/analyzers/xss/analyzer.go` around lines 35 - 36, The initial
nil-check should also guard options.HttpClient to avoid a panic when calling
options.HttpClient.Do; update the validation in the beginning of the function
(the block checking options and options.FuzzGenerated.Component) to also check
options.HttpClient != nil and return the same false, empty string, nil triple if
it's nil so subsequent calls to options.HttpClient.Do are safe.
pkg/fuzz/analyzers/xss/analyzer_test.go (1)

19-40: Use the payload variable in fixtures instead of hardcoded literals.

Line [10] defines payload, but Lines [19], [24], [29], [34], and [39] inline "pwned_payload". This can drift if the payload changes.

♻️ Proposed refactor
 import (
+	"fmt"
 	"testing"
 
 	"github.com/stretchr/testify/require"
 )
@@
 		{
 			name:     "HTML Text Context",
-			htmlBody: "<html><body>Hello pwned_payload world</body></html>",
+			htmlBody: fmt.Sprintf("<html><body>Hello %s world</body></html>", payload),
 			expected: "HTML Text",
 		},
 		{
 			name:     "Script Block Context",
-			htmlBody: "<html><script>var a = 'pwned_payload';</script></html>",
+			htmlBody: fmt.Sprintf("<html><script>var a = '%s';</script></html>", payload),
 			expected: "Script Block",
 		},
 		{
 			name:     "Attribute Value Context",
-			htmlBody: "<input type='text' value='pwned_payload'>",
+			htmlBody: fmt.Sprintf("<input type='text' value='%s'>", payload),
 			expected: "Attribute Value (input[value])",
 		},
 		{
 			name:     "Attribute Name Context",
-			htmlBody: "<svg pwned_payload='1'>",
+			htmlBody: fmt.Sprintf("<svg %s='1'>", payload),
 			expected: "Attribute Name (svg)",
 		},
 		{
 			name:     "HTML Comment Context",
-			htmlBody: "<!-- pwned_payload -->", // ← fix: payload add kiya
+			htmlBody: fmt.Sprintf("<!-- %s -->", payload),
 			expected: "HTML Comment",
 		},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/fuzz/analyzers/xss/analyzer_test.go` around lines 19 - 40, Tests in
analyzer_test.go are embedding the literal "pwned_payload" instead of using the
declared payload variable, which will drift if payload changes; update the
table-driven fixtures (entries named "HTML Text", "Script Block", "Attribute
Value (input[value])", "Attribute Name (svg)", and "HTML Comment") to build
their htmlBody using the payload variable (e.g., via string concatenation or
fmt.Sprintf) rather than the hardcoded literal so all occurrences reference the
single payload constant; ensure the variable name payload is used exactly and
that surrounding quotes/markup remain correct for each htmlBody.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/fuzz/analyzers/xss/analyzer.go`:
- Around line 39-42: The component's current fuzz value isn't being set before
rebuilding, causing stale state: before calling Rebuild() on
options.FuzzGenerated.Component (and similarly on gr.Component), call the
component's SetValue with the current key and payload (e.g.,
options.FuzzGenerated.Component.SetValue(gr.Key, payload) or
gr.Component.SetValue(gr.Key, payload)) and then call Rebuild() on the same
component instance (do not clone) so the rebuilt request uses the correct,
per-request state.

---

Nitpick comments:
In `@pkg/fuzz/analyzers/xss/analyzer_test.go`:
- Around line 19-40: Tests in analyzer_test.go are embedding the literal
"pwned_payload" instead of using the declared payload variable, which will drift
if payload changes; update the table-driven fixtures (entries named "HTML Text",
"Script Block", "Attribute Value (input[value])", "Attribute Name (svg)", and
"HTML Comment") to build their htmlBody using the payload variable (e.g., via
string concatenation or fmt.Sprintf) rather than the hardcoded literal so all
occurrences reference the single payload constant; ensure the variable name
payload is used exactly and that surrounding quotes/markup remain correct for
each htmlBody.

In `@pkg/fuzz/analyzers/xss/analyzer.go`:
- Around line 35-36: The initial nil-check should also guard options.HttpClient
to avoid a panic when calling options.HttpClient.Do; update the validation in
the beginning of the function (the block checking options and
options.FuzzGenerated.Component) to also check options.HttpClient != nil and
return the same false, empty string, nil triple if it's nil so subsequent calls
to options.HttpClient.Do are safe.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10421e9 and 1d9569c.

📒 Files selected for processing (2)
  • pkg/fuzz/analyzers/xss/analyzer.go
  • pkg/fuzz/analyzers/xss/analyzer_test.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant