fix: use safe type assertions in HTTP operators to prevent panics#7223
Conversation
Unsafe type assertions without ok checks cause panics when the data map contains unexpected types. This can crash the scanner when processing malformed responses or corrupted internal state.
Neo - PR Security ReviewNo security issues found Highlights
Hardening Notes
Comment |
WalkthroughThe changes modify type assertion handling in HTTP operator code, replacing direct assertions with safer comma-ok patterns to prevent panics when types don't match expected values during response handling and event creation. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
pkg/protocols/http/operators.go (2)
34-35: Prefertypes.ToStringhere to preserve snippets for non-string responses.Line 34 is panic-safe now, but it turns non-string values into an empty snippet. Converting via
types.ToStringkeeps behavior resilient without losing snippet content.Proposed tweak
- responseStr, _ := data["response"].(string) + responseStr := types.ToString(data["response"]) return matcher.Result(matcher.MatchStatusCode(statusCode)), []string{responsehighlighter.CreateStatusCodeSnippet(responseStr, statusCode)}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/protocols/http/operators.go` around lines 34 - 35, The code is using a direct string type assertion on data["response"] (responseStr := data["response"].(string)) which drops non-string snippet content; replace that assertion by converting via types.ToString(data["response"]) and pass the resulting string into responsehighlighter.CreateStatusCodeSnippet so non-string responses retain their snippet content while keeping the panic-safe behavior in the matcher.Result/matcher.MatchStatusCode flow.
183-187: Use a fallback forInfoto avoid losing template metadata on type mismatch.Line 183 avoids panic, but a failed assertion yields zero-value
model.Info, which can degrade result quality. Consider defaulting torequest.options.TemplateInfo.Proposed tweak
- info, _ := wrapped.InternalEvent["template-info"].(model.Info) + info, ok := wrapped.InternalEvent["template-info"].(model.Info) + if !ok { + info = request.options.TemplateInfo + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/protocols/http/operators.go` around lines 183 - 187, When building the output.ResultEvent, don't rely solely on the type assertion info, because wrapped.InternalEvent["template-info"].(model.Info) can yield a zero-value on mismatch; instead check the assertion result and if it fails use the request.options.TemplateInfo as a fallback for the Info field. Update the construction of output.ResultEvent (the TemplateID/TemplatePath/Info block where wrapped.InternalEvent is read) to perform a safe type assertion (ok pattern) and assign request.options.TemplateInfo when ok is false or the value is empty so template metadata isn't lost.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@pkg/protocols/http/operators.go`:
- Around line 34-35: The code is using a direct string type assertion on
data["response"] (responseStr := data["response"].(string)) which drops
non-string snippet content; replace that assertion by converting via
types.ToString(data["response"]) and pass the resulting string into
responsehighlighter.CreateStatusCodeSnippet so non-string responses retain their
snippet content while keeping the panic-safe behavior in the
matcher.Result/matcher.MatchStatusCode flow.
- Around line 183-187: When building the output.ResultEvent, don't rely solely
on the type assertion info, because
wrapped.InternalEvent["template-info"].(model.Info) can yield a zero-value on
mismatch; instead check the assertion result and if it fails use the
request.options.TemplateInfo as a fallback for the Info field. Update the
construction of output.ResultEvent (the TemplateID/TemplatePath/Info block where
wrapped.InternalEvent is read) to perform a safe type assertion (ok pattern) and
assign request.options.TemplateInfo when ok is false or the value is empty so
template metadata isn't lost.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f78fd870-b707-4ba7-a9c5-8242ae125f2a
📒 Files selected for processing (1)
pkg/protocols/http/operators.go
dwisiswant0
left a comment
There was a problem hiding this comment.
Please file an issue before submitting fix patches.
Include reproduction steps as per the template and the exact nuclei command that crashes (or custom runner PoC for Nuclei SDK). The reproduction must be based on a realistic execution path that is fully concrete and reproducible.
Thanks!
Proposed Changes
The HTTP protocol operators contain 4 unsafe type assertions that will panic and crash the entire nuclei process if the internal event data map contains unexpected types. This is a reliability and denial-of-service concern — a malformed HTTP response or corrupted internal state triggers an unrecoverable panic instead of graceful error handling.
Root Cause
Go type assertions of the form
x.(Type)without a secondokreturn value cause a runtime panic if the value is not of the expected type. The HTTP operators use this unsafe pattern in several places where the data originates from HTTP responses (which are attacker-controlled in a scanning context).Unsafe Assertions Fixed
data["response"].(string)responseStr, _ := data["response"].(string)value.(bool)isGlobalMatchers, _ = value.(bool)value.(string)analyzerDetails, _ = value.(string)wrapped.InternalEvent["template-info"].(model.Info)info, _ := wrapped.InternalEvent["template-info"].(model.Info)Crash Scenarios
Scenario 1: Malformed response processing
responsekey in the data map to be stored as[]byteinstead ofstringdata["response"].(string)panics → nuclei crashesScenario 2: Corrupted internal event during concurrent execution
template-infoto be missing from the internal event mapwrapped.InternalEvent["template-info"].(model.Info)panics on nil interface → nuclei crashesScenario 3: Plugin/extension type mismatch
global-matcherskeyvalue.(bool)panics → nuclei crashesThe Fix
All 4 assertions now use Go's safe type assertion pattern
value, ok := x.(Type)which returns the zero value instead of panicking when the type doesn't match. This is the idiomatic Go approach and is already used correctly elsewhere in the same file (e.g., line 52-60 ingetStatusCode).Files Changed
pkg/protocols/http/operators.go— 4 unsafe type assertions replaced with safe comma-ok patternSecurity Impact
Proof
The fix follows the exact same safe assertion pattern already used in the same file:
Checklist
devbranchSummary by CodeRabbit