The file was referenced by //go:embed but never committed,
causing build failures when consumed as a remote Go module.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Supports check mode (exploit verification via finger field) and brute mode
(default credential testing via zombie/tags field). POC templates are only
executed against targets whose fingerprints match, avoiding blind scanning.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Root cause: the atomic.Bool + polling monitor goroutine pattern had a
race between wg.Wait() in the monitor and wg.Add(1) in the main loop.
When the monitor observed done=true and started Wait, the main loop
could still dispatch new work, causing Close().wg.Wait() to hang.
Fix: replace with nil-channel + sync.Once pattern. When the word stream
exhausts or limit is hit, worderCh is set to nil (disabling that select
branch permanently), then a single goroutine waits for wg to reach zero.
Since wg.Add(1) only occurs in the worderCh branch, nil-ing it before
Wait guarantees no new Add after Wait starts — no race possible.
Other fixes:
- Task feeder goroutine now ctx-aware (prevents leak on cancel)
- AddPool checks Invoke error (prevents poolwg counter mismatch)
- Revert resource_provider IIFE (reading a struct field cannot panic)
- Remove E2E -short skip (race is fixed, full coverage in CI)
- Fix Go 1.24+ vet: non-constant format strings in Init()
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Bug fixes:
- Defer scopeLocker.Unlock in doScopeCrawl (deadlock on panic)
- Defer statsMu.Unlock in recordStat (deadlock on panic)
- Defer RUnlock in resource_provider.LoadConfig via inline func
- Fix data race in invoke(): move bl field writes before doRedirect
- Close response body on ReadAll error (connection leak)
- Add defer raw.Close() for raw file parsing (fd leak)
- Safe type assertion in load.go keyword parsing (panic on bad YAML)
- Check ants pool creation errors in NewBrutePool/NewCheckPool
New tests (15 test functions):
- pool_test.go: scopeLocker panic recovery, cancel mid-processing,
single-threaded map access, valid pool creation
- runner_test.go: concurrent recordStat safety, nil stat handling
- load_test.go: malformed YAML tolerance, valid YAML loading
- e2e_test.go: normal brute scan, context cancellation, server errors,
WAF behavior, multi-target check mode, mixed status codes
CI hardening:
- Add -race detector (Linux, -short mode)
- Add -timeout 300s to prevent deadlock hangs
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- go:generate now uses -embed flag to produce //go:embed binary data
- templates.go reduced from 125KB base64 source to 0.9KB + 93KB .bin files
- binary saves ~28KB (removes base64 decode overhead at runtime)
- templates submodule updated with embed-aware generator
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Replace close(additionCh) with additionClosed atomic.Bool flag to
prevent panic when async producers (redirect/crawl/retry/append)
write after pool shutdown
- Guard addAddition() with ctx.Err() and additionClosed check before send
- ParseRawResponse failure no longer marks baseline as invalid or
returns early; log at debug level instead
- Read Location header from live response (resp.GetHeader) instead of
re-parsed bl.Response.Header for reliability
- Add ParseRawResponse boundary tests (nil, empty, truncated, binary, etc.)
Co-Authored-By: Claude Opus 4.6 <[email protected]>