- recenter the detection confidence (sigmoid centered at 0.3) so a single weak
signature match no longer clears the 0.5 threshold. before, sigmoid(0) was 0.5
so *any* match counted as a detection - that's the magento-on-a-plain-page
false positive from the live run. real detections match ~50%+ of signature
weight, so the existing detector tests are unaffected
- getVulnerabilities matched affected versions with a raw string prefix, so "4.2"
also matched "4.20"; match only on dotted boundaries now
- break confidence ties on name so the picked framework is deterministic
- add regression tests for the confidence floor and the version boundary
- make the four wordlist base urls (dirlist/dnslist/git/ports) package vars
instead of consts so tests can repoint them at a local fixture; the default
values are byte-for-byte unchanged
- add internal/scan/integration_test.go behind a //go:build integration tag: it
stands up a local "vulnerable app" httptest server with planted artifacts and
runs git/dirlist/cms/headers/sql/lfi/ports against it, asserting real findings
- go.yml runs them via `go test -tags=integration`; the default test run is
untouched (the tag keeps them out)
- document the integration run in docs/development.md
- add internal/version: resolve from the release ldflag, else the go build
info (module tag / vcs revision), else "dev"
- show the version on the boot banner and for `sif version`
- Makefile now stamps `make` builds via git describe (matching the release ci),
so local/go-install builds report a real version instead of "dev"
- patchnotes.ShowOnce skips pseudo/dev versions so non-release builds dont make
a doomed github call
- document sif version / sif patchnote / SIF_NO_PATCHNOTES in the readme + usage
doSupabaseRequest and the signup call used a bare http.Client{} with no
timeout, so a slow supabase project could hang the whole js scan. thread the
scan's --timeout down through ScanSupabase into every supabase request.
`strings.Split(url, "://")[1]` was copy-pasted in 18 spots and panics on a
schemeless target (index out of range). add a small stripScheme helper in the
scan package - and a guarded equivalent in logger, which cant import scan - so
a bare host degrades gracefully instead of crashing the scan.
- `sif patchnote` (also `-pn`) fetches the latest github release and renders
its notes with glamour
- on the first run of a new version those notes are shown once, then recorded
so they dont show again - best-effort, so dev builds, the SIF_NO_PATCHNOTES
opt-out, and any network failure stay quiet
- wire up `var version` so the release `-X main.version` ldflag actually lands,
and add `sif version`
strips the emoji from the subdomaintakeover/cloudstorage/supabase log
prefixes and trims comments that just restate the code (the
parameters/returns block on SubdomainTakeover, a couple of "this provides
type safety" notes) so the scanners read like whois.go/headers.go.
internal/worker.Pool[T,R] (run/runwithfilter/foreach) was added with tests
but never wired into anything - the scanners all hand-roll their own
waitgroup loops. dead weight, so remove it.
- git.go and dork.go appended to a shared results slice from every worker
goroutine with no mutex - a real race that -race never caught since
neither has a test. guard the appends like dirlist/dnslist already do.
- progress.go's non-tty milestone path divided by total with no guard, so
a zero-total bar panicked when output was piped/redirected. bail early
on total <= 0 to match the tty branch, and add an output test for it.
adds a -sh/--security-headers scan that flags missing or weak response
headers (hsts, csp, x-frame-options, x-content-type-options,
referrer-policy, permissions-policy, coop) and headers that leak server
internals (server, x-powered-by, ...). hsts is only graded over https
where it actually applies. wired into App.Run and the module results.
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.
The nuclei-templates tarball is fetched over the network and its entry
names flowed directly into os.Mkdir/os.Create, so a malicious or
compromised archive could write outside the extraction directory
("Zip Slip", CWE-22). Resolve each entry against the working directory
and reject any path that escapes it before touching the filesystem.
CodeQL flagged this as a high-severity alert on the lines this branch
already touched. gosec's G305 fires on filepath.Join with archive data
regardless of the traversal guard, so it's excluded with a note.
- 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
Set the HostErrorsCache executor option, cache is created but not passed
as option.
Headless initialization is required even without browser templates.
Nuclei expects project file to be set
- Add output package with colored prefixes and module loggers
- Each module gets unique background color based on name hash
- Add spinner for indeterminate operations
- Add progress bar for known-count operations
- Update all scan files to use ModuleLogger pattern
- Add clean PrintSummary for scan completion