hunter-party-go/security-hunter-go/SKILL.md
Audit Go code for security vulnerabilities — hardcoded secrets, injection risks (SQL, command, template, path), missing input validation at trust boundaries, insecure defaults, auth gaps, sensitive data exposure, unsafe package usage, and weak crypto. Use when: reviewing Go code before deployment, auditing trust boundaries, preparing for a security review, onboarding third-party integrations, or hardening an application.
npx skillsauth add skyosev/agent-skills security-hunter-goInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Audit code for security vulnerabilities — places where untrusted input flows into sensitive operations without validation, secrets are embedded in source, defaults are permissive, or auth checks are missing. The goal: every trust boundary validates its inputs, no secrets live in code, and the principle of least privilege is applied throughout.
Trust boundaries are the perimeter. Every point where external data enters the system — HTTP requests, gRPC calls, file uploads, environment variables, database reads, third-party API responses — is a trust boundary. Input must be validated, sanitized, or escaped before it flows into operations that could be exploited.
Secrets belong in the environment, never in code. API keys, passwords, tokens, certificates, and connection strings must come from environment variables, secret managers, or encrypted config — never from source files, comments, or committed config.
Default to deny. Defaults should be restrictive: CORS origins explicit not *, auth required not optional,
permissions minimal not broad. Permissive defaults are the most common class of security misconfiguration.
Defense in depth. No single validation layer is sufficient. Validate at the boundary, escape at the output, enforce at the data layer. If one layer fails, another should catch the exploit.
Fail closed. When auth/authz checks fail or return errors, the result should be denial, not access. Error paths must not bypass security controls.
API keys, passwords, tokens, or connection strings embedded directly in source code.
Signals:
sk_live_, AKIA, ghp_, Bearer , password=postgres://user:pass@host.env files or secret-bearing config committed to the repoconst or var declarations with secret-looking valuesAction: Move to environment variables or a secret manager. Add the pattern to .gitignore. Rotate any committed
secret immediately — it's already compromised if the repo was ever shared.
Untrusted input concatenated into strings that are interpreted as code, queries, or commands.
Signals:
fmt.Sprintf in query strings instead of parameterized queries (db.Query(sql, args...))exec.Command with user-controlled arguments, especially via shell (sh -c)os.Open(), filepath.Join(), or URL construction without canonicalizationtext/template in a web/HTML context (no auto-escaping) instead of
html/template. Note: text/template is fine for non-HTML output (config files, CLI output, code generation)regexp.Compile (ReDoS risk)Action: Use parameterized queries, allowlists, filepath.Clean + prefix checking, html/template, or regex
escaping. Never concatenate untrusted input into interpreted strings.
Endpoints, handlers, or integration points that accept external data without validation.
Signals:
r.Body, r.URL.Query(), or r.FormValue() without validationos.Args or flag values without validationAction: Add validation at every trust boundary. Validate type, format, range, and length. Reject invalid input explicitly — don't coerce or default.
Permissive defaults that weaken security posture when not explicitly overridden.
Signals:
Access-Control-Allow-Origin: * or credentials with wildcard originInsecureSkipVerify: true in tls.ConfigReadTimeout, WriteTimeout, IdleTimeout)Secure, HttpOnly, or SameSite attributesos.WriteFile with 0666 or 0777)Action: Restrict defaults. Require explicit opt-in for permissive settings with justification.
Missing or inconsistent auth checks that allow unauthorized access or privilege escalation.
Signals:
Action: Ensure every endpoint has explicit auth/authz. Check authorization server-side against the session, not client-provided claims. Use bcrypt/scrypt/argon2 for password hashing.
Personal data, secrets, or internal details leaked through logs, errors, responses, or storage.
Signals:
log.Printf("%+v", request))fmt.Errorf that include sensitive context sent to clientspanic stack traces exposed to clients in productionAction: Strip sensitive fields from logs and error responses. Use separate internal/external error messages. Recover panics in HTTP middleware and return generic errors.
Usage of unsafe, reflect, or CGO that bypasses Go's type safety and memory safety.
Signals:
import "unsafe" outside of performance-critical, well-audited codereflect used to bypass unexported field access//go:linkname directives accessing internal runtime functions//go:nosplit, //go:noescape pragmas without justificationunsafe.Pointer arithmetic for memory manipulationAction: Audit each usage. Ensure unsafe code is isolated, documented, and justified. Verify CGO boundaries validate all inputs. Prefer pure Go alternatives where possible.
Race conditions, deadlocks, and resource leaks that can be exploited or cause denial of service.
Signals:
sync.Mutex used inconsistently (locked in some paths but not others)context.Contextsync.WaitGroup with Add called in the wrong goroutineAction: Use -race detector in tests. Protect shared state with appropriate synchronization. Bound goroutine
creation. Use context.Context for cancellation.
Module dependencies with known vulnerabilities or integrity issues.
Signals:
go.sum not committed to the repogovulncheck)replace directives in go.mod pointing to local paths in productionGONOSUMCHECK / GONOSUMDB awareness (sumdb trust model)Action: Commit go.sum. Run govulncheck. Pin dependency versions. Audit transitive dependencies for
security-sensitive code paths.
main/master)BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo main)
SCOPE=$(git diff --name-only $(git merge-base HEAD $BASE)...HEAD)
Constrain all subsequent scans to the resolved surface.EXCLUDE='--glob !**/vendor/** --glob !**/testdata/** --glob !**/*_test.go'
# Hardcoded secrets (common patterns)
rg --pcre2 '(sk_live_|AKIA|ghp_|password\s*=\s*"|secret\s*=\s*")' $EXCLUDE
rg --pcre2 '(postgres|mysql|mongodb)://\w+:\w+@' $EXCLUDE
# SQL injection: string formatting in queries
rg --pcre2 '(Query|Exec|QueryRow)\s*\(\s*(fmt\.Sprintf|".*\+|`.*\+)' --type go $EXCLUDE
rg 'fmt\.Sprintf.*SELECT|fmt\.Sprintf.*INSERT|fmt\.Sprintf.*UPDATE|fmt\.Sprintf.*DELETE' --type go $EXCLUDE
# Command injection
rg 'exec\.Command\s*\(' --type go $EXCLUDE
rg 'os/exec' --type go $EXCLUDE
# Path traversal
rg '(os\.Open|os\.ReadFile|os\.Create|ioutil\.ReadFile)' --type go $EXCLUDE
# Template injection (text/template used in web/HTML context — triage: check if output is served to browsers)
rg '"text/template"' --type go $EXCLUDE
# Insecure TLS
rg 'InsecureSkipVerify\s*:\s*true' --type go $EXCLUDE
# Unsafe package
rg '"unsafe"' --type go $EXCLUDE
rg 'go:linkname' --type go $EXCLUDE
# Weak crypto (math/rand is only a concern in security-sensitive contexts like token generation)
rg '"crypto/md5"|"crypto/sha1"' --type go $EXCLUDE
rg '"math/rand"' --type go $EXCLUDE
# Missing HTTP timeouts
rg 'http\.ListenAndServe|&http\.Server\{' --type go $EXCLUDE
# Sensitive data in logs
rg --pcre2 'log\.\w+\(.*\b(password|token|secret|authorization|cookie)\b' -i --type go $EXCLUDE
# File permissions
rg '0666|0777|os\.ModePerm' --type go $EXCLUDE
# pprof in non-debug code
rg 'net/http/pprof|runtime/pprof' --type go $EXCLUDE
# Regex from user input
rg 'regexp\.(Compile|MustCompile)' --type go $EXCLUDE
# Unbounded goroutines from user input
rg 'go\s+func|go\s+\w+\(' --type go $EXCLUDE
For each trust boundary found in Phase 1:
exec.Command, a SQL query, or template rendering?Save as YYYY-MM-DD-security-hunter-audit-{$LLM-name}.md in the project's docs folder (or project root if no docs folder exists).
# Security Hunter Audit — {date}
## Scope
- Surface: {diff / path / codebase}
- Files: {count or list}
- Exclusions: {list}
## Trust Boundary Map
| # | Boundary | Location | Validation | Auth |
| - | -------- | -------- | ---------- | ---- |
| 1 | POST /api/users | file:line | Struct validation | JWT middleware |
| 2 | Webhook /hooks/stripe | file:line | None | None |
## Findings
### Hardcoded Secrets
| # | Location | Pattern | Severity | Action |
| - | -------- | ------- | -------- | ------ |
| 1 | file:line | `sk_live_...` Stripe key | Critical | Move to env, rotate immediately |
### Injection Risks
| # | Location | Type | Untrusted Input | Action |
| - | -------- | ---- | --------------- | ------ |
| 1 | file:line | SQL injection | `r.URL.Query().Get("id")` in fmt.Sprintf | Use parameterized query |
### Missing Input Validation
| # | Location | Boundary | Input | Action |
| - | -------- | -------- | ----- | ------ |
| 1 | file:line | POST /api/orders | `json.Decode` without validation | Add struct validation |
### Insecure Defaults
| # | Location | Setting | Current | Action |
| - | -------- | ------- | ------- | ------ |
| 1 | file:line | TLS verification | `InsecureSkipVerify: true` | Remove or justify |
### Auth/Authz Gaps
| # | Location | Endpoint | Issue | Action |
| - | -------- | -------- | ----- | ------ |
| 1 | file:line | GET /admin/users | No auth middleware | Add admin auth |
### Sensitive Data Exposure
| # | Location | Data | Channel | Action |
| - | -------- | ---- | ------- | ------ |
| 1 | file:line | Auth token | log.Printf | Remove from logs |
### Unsafe/CGO Risks
| # | Location | Pattern | Risk | Action |
| - | -------- | ------- | ---- | ------ |
| 1 | file:line | `unsafe.Pointer` arithmetic | Memory corruption | Audit and document |
### Concurrency Safety
| # | Location | Pattern | Risk | Action |
| - | -------- | ------- | ---- | ------ |
| 1 | file:line | Shared map without mutex | Race condition | Add sync.RWMutex |
### Dependency / Supply-Chain Risks
| # | Location | Issue | Severity | Action |
| - | -------- | ----- | -------- | ------ |
| 1 | go.mod | No go.sum committed | High | Commit go.sum |
## Recommendations (Priority Order)
1. **Critical**: {hardcoded secrets to rotate, injection vulnerabilities, auth bypasses}
2. **Must-fix**: {missing input validation, insecure defaults, auth gaps, dependency CVEs}
3. **Should-fix**: {sensitive data exposure, unsafe usage, concurrency issues, supply-chain hygiene}
file/path.go:line with the exact code.SameSite cookie attribute. Prioritize accordingly.regexp.MustCompile with a hardcoded pattern is fine. regexp.Compile(userInput)
is a ReDoS risk. Grep finds both — judgment separates them.development
Transforms vague feature ideas into precise, codebase-grounded technical requirements. Use when requirements are ambiguous/incomplete, the user struggles to describe behavior, terminology is unclear, or multiple concepts are mixed. Output is a requirements spec—NOT an implementation plan.
tools
Audit TypeScript type definitions for design debt — duplicated shapes, missing derivations, over-engineered generics, under-constrained type parameters, reinvented utility types, and disorganized type architecture. Type structure and maintainability, not type enforcement. Use when: reviewing type definitions for maintainability, reducing type duplication, simplifying over-engineered type-level logic, or reorganizing type architecture after growth.
development
Audit TypeScript test code for quality gaps — missing coverage on critical paths, brittle tests coupled to implementation, over-mocking, assertion-free tests, missing edge cases, and duplicated test setup. Focuses on test effectiveness, not production code structure. Use when: reviewing TypeScript test suites for reliability, reducing false-positive test failures, improving coverage of critical business logic, or cleaning up test debt.
tools
Audit TypeScript class and interface design for SOLID violations — god classes, rigid extension points, broken substitutability, fat interfaces, and concrete dependency chains. Focuses on responsibility assignment and abstraction fitness. Use when: reviewing class hierarchies, preparing for extension with new variants, reducing coupling between services, or improving testability of class-heavy code.