The attack field was parsed but never read, so every module ran the
clusterbomb cross-product. Honor it: pitchfork pairs path[i] with
payload[i] and stops at the shorter list, clusterbomb stays the default.
Unknown attack values are rejected at parse time instead of silently
ignored.
the engine declared size matchers and kv extractors but the executor
dropped them (size fell through to the default case, kv was never read).
wire both: size matches the response body length in bytes, kv records
every response header as a key-value pair namespaced by the extractor
name.
this unblocks the headers.go conversion in #52, which needs a full header
dump the known-set regex extractors cannot reproduce; the headers.yaml
module and the headers.go removal are a separate follow-up. the extractor
is named kv to match docs/modules.md (the struct comment said kval). the
declared json extractor stays deferred since it needs a json-path
dependency and a path-syntax decision.
refs #52
the yaml module engine (the user-facing extensibility surface) had 0%
test coverage. add table-driven tests for the matcher types
(status/word/regex + and/or + negative), checkWords/checkRegex (incl
invalid-pattern fail-closed under AND, skip under OR), runExtractors
(regex capture groups, group-index bounds, part selection),
substituteVariables and generateHTTPRequests (path x payload expansion),
and ParseYAMLModule on valid + malformed yaml. drive ExecuteHTTPModule
end-to-end against an httptest server through the shared httpx client so
matcher hits and extractor captures are exercised for real. coverage
0% -> 93.7%.
also: ExecuteDNSModule/ExecuteTCPModule were stubs returning an empty
result with nil error, so a type:dns/type:tcp module silently reported
"0 findings" - indistinguishable from a real clean scan. make them
return ErrUnsupportedModuleType (sentinel, wrapped with the module id) so
the existing caller logs a clear failure instead. a test pins the new
behavior.
bodyclose is excluded for test files in .golangci.yml: the synthetic
*http.Response fixtures carry no socket, mirroring the existing _test.go
slack for errcheck/noctx/gosec.
rolls the (c) 2022-2025 banner to 2022-2026 across all go files, the
startup banner in sif.go, and the header-check workflow's expected
format. comment-only, nothing else changes.
- noctx: use http.NewRequestWithContext instead of http.Get/client.Get
- bodyclose: close response bodies on all code paths
- httpNoBody: use http.NoBody instead of nil for GET request bodies
- ifElseChain: convert if/else chains to switch in sif.go
- sloppyReassign: use := in logger.go where possible
- nilnil: annotate intentional nil,nil returns in lfi.go, sql.go
- errcheck: handle template install error in nuclei.go
- govet copylock: pass mutex by pointer in executor.go
- log.Fatalf: replace with log.Errorf+continue in api mode