Embed proton's found/keys templates (156 rules covering AWS, GCP, Azure,
OpenAI, Slack, GitHub, Stripe, etc.) into the spray binary. The new --keys
flag activates them; -a (advance) also enables keys automatically. When
used with --recon, tags are merged into a single EnableExtractors call.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Mirrors gogo's ResourceLoader pattern. SDK spray engine sets it to
no-op after init, preventing RunWithArgs from reloading ports/fingers/templates.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- parsers.Extracted: add Severity and Items (ExtractItem with ctx/line/offset)
- ProtonExtract: preserve severity from templates, capture N-char context around matches
- Add --extract-context CLI flag (default 0, e.g. --extract-context 50)
- Add word matchers pre-filtering to 14 existing templates for performance
- Add 9 new HaE-inspired rules: lfi-indicator, upload-form, url-as-value,
location-redirect, mac-address, sensitive-field, linkfinder, url-schemes,
authorization-header
- Total proton templates: 45 (was 35)
- Update ColorString/TreeString to render severity and context
- Comprehensive tests for severity, context, new templates, tag mappings
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
go generate with the updated templates submodule (7d5675c) produces
different embedded data and code. Key changes:
- cmd/cmd.go: logs.Info/Important → logs.InfoLevel/ImportantLevel
- pkg/templates.go: remove proton_rules.bin/neutron.bin embeds (no longer needed)
- core/baseline: use ProtonExtract instead of Extractors.Extract
- core/format: list proton extractor names
- Update embedded binary data files
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
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]>