* fix(taint): gate *http.Request auto-taint on entry-point detection (#1629)
isParameterTainted unconditionally tainted any *http.Request parameter by
type, even when the function had known callers passing constant-URL requests.
Check the CHA call graph first: only auto-taint when the function has no
in-edges (true external entry point). When callers exist, fall through to
the existing caller-verification loop instead.
Fixes#1629
* Address Barry AI Security Analysis
* improve code coverage
* fix lint
* taint mechanism, framework agnostic
* address lint warning
* fix(G118): eliminate false positive for package-level cancel variables
G118 was incorrectly reporting context cancellation function not called
when the cancel function was assigned to a package-level variable (e.g.,
in init()) and called in a separate function (e.g., signal handler).
Root cause: isCancelCalled() lacked special handling for *ssa.Global
(package-level variables), causing cross-function tracking to fail.
Solution: Add dedicated tracking for package-level globals, similar to
the struct field handling added in PR #1596. The fix includes:
- Check in *ssa.Store case to detect global variable assignments
- isGlobalCalledInAnyFunc() helper to search all functions for calls
- isValueCalled() generalized helper for BFS value tracking
* additional test
* fix(G118): eliminate false positive when cancel stored in struct field post-construction
When a cancel function is assigned to a struct field after construction
(e.g. s.cancel = cancel), the SSA FieldAddr for the store is a distinct
value from any FieldAddr created later for defer s.cancel() or inside a
closure. The existing isCancelCalledViaStructField only matched receiver
methods and missed these patterns.
Add isFieldCalledInAnyFunc which scans all SSA functions (including
closures) for a FieldAddr with matching struct pointer type and field
index, then checks whether the loaded value is called. As a side effect,
this also resolves the known false positive for nested struct field access.
fixes: 1595
* update rules documentation
Analyzer.Process fans out package walks across goroutines that previously
shared a single rule set. Rules with mutable per-package state — specifically
readfile (G304), whose cleanedVar/joinedVar maps are written and read across
goroutines — raced fatally under concurrency. The fix stores the RuleBuilder
functions after LoadRules and calls buildPackageRuleset() at the start of each
checkRules invocation, giving every concurrent worker its own freshly allocated
rule instances with no shared mutable state and no locks required. Stale map
entries no longer leak across package boundaries, closing a secondary
false-negative bug as a side-effect.
fixes: 1586
* fix(G705): eliminate false positive for non-HTTP io.Writer
Adds ArgTypeGuards map[int]string to taint.Sink. The XSS analyzer now
requires arg[0] of fmt.Fprint* to implement net/http.ResponseWriter.
Writing exec pipe output to os.Stdout no longer triggers G705.
Fixes: #1548
* improve code coverage
* feat: add taint analysis engine for data flow security
Implements SSA-based taint analysis to detect security vulnerabilities:
- G701: SQL injection via string concatenation
- G702: Command injection via user input
- G703: Path traversal via user input
- G704: SSRF via user-controlled URLs
- G705: XSS via unescaped user input
- G706: Log injection via user input
Uses golang.org/x/tools for SSA/call graph analysis with CHA.
Zero external dependencies beyond existing gosec imports.
Add line-based fallback for nosec comment detection when ast.CommentMap
fails to associate comments correctly. This fixes the case where #nosec
comments at the end of lines with open brackets were being ignored.
Refactor duplicate parsing logic into parseNoSecDirective helper function
to reduce code complexity and improve maintainability.
* feat: add debug build profiling support
Add CPU and memory profiling capabilities for debug builds using Go build
tags. Profiling code is completely excluded from release builds.
Changes:
- Add profiling_debug.go with -cpuprofile and -memprofile flags (build tag: debug)
- Add build-debug and build-debug-race Makefile targets
- Refactor main() to run() pattern for proper defer handling
- Replace logger.Fatal() with logger.Printf() + return for clean exits
- Pass logger to profiling for consistent [gosec] log prefix
Usage:
make build-debug
./gosec-debug -cpuprofile cpu.prof -memprofile mem.prof ./...
* Refactor profiling: encapsulate state and improve error handling
- Encapsulate profiling state in Profiler struct to eliminate package-level mutable state
- Add proper error handling with error returns instead of silent failures
- Add exit code constants (exitSuccess/exitFailure) to replace magic numbers
- Fix Makefile clean target to remove gosec-debug binary
- Add nil logger guard for safety
* Use exit constants in all return statements
Replace remaining magic numbers (0, 1) with exitSuccess and exitFailure
constants throughout the run() function for consistency.
---------
Co-authored-by: Oittaa <eero@oittaa.net>
* add path-based rule exclusions
Implements #1287
* Ssupport for excluding specific rules from specific paths, enabling large monorepos to apply different security rules to different components (e.g., CLI tools vs services).
* fix formatting issuue with path filter test to pass gci