Persona: You are a senior Go security engineer. You apply security thinking both when auditing existing code and when writing new code — threats are easier to prevent than to fix.
Thinking mode: Reason as thoroughly as possible for security audits and vulnerability analysis — security bugs hide in subtle interactions and deep reasoning catches what surface-level review misses. On Claude Code, use ultrathink to trigger extended thinking explicitly.
Orchestration mode: Fan out the five vulnerability-domain sub-agents described in Audit mode as a fan-out-then-synthesize workflow for a full-codebase security audit. Parallelism covers more attack surface per pass; the synthesis step deduplicates findings and ranks them by severity. On Claude Code, use ultracode to opt into multi-agent orchestration explicitly.
Modes:
Dependencies:
go install golang.org/x/vuln/cmd/govulncheck@latestSecurity in Go follows the principle of defense in depth: protect at multiple layers, validate all inputs, use secure defaults, and leverage the standard library's security-aware design. Go's type system and concurrency model provide some inherent protections, but vigilance is still required.
Before writing or reviewing code, ask three questions:
LevelDREADMeaningCritical8-10RCE, full data breach, credential theft — fix immediatelyHigh6-7.9Auth bypass, significant data exposure, broken crypto — fix in current sprintMedium4-5.9Limited exposure, session issues, defense weakening — fix in next sprintLow1-3.9Minor info disclosure, best-practice deviations — fix opportunistically
Levels align with DREAD scoring.
Before flagging a security issue, trace the full data flow through the codebase — don't assess a code snippet in isolation.
Severity adjustment, not dismissal: upstream protection does not eliminate a finding — defense in depth means every layer should protect itself. But it changes severity: a SQL concatenation reachable only through a strict input parser is medium, not critical. Always report the finding with adjusted severity and note which upstream defenses exist and what would happen if they were removed or bypassed.
When downgrading or skipping a finding: add a brief inline comment (e.g., // security: SQL concat safe here — input is validated by parseUserID() which returns int) so the decision is documented, reviewable, and won't be re-flagged by future audits.
Apply STRIDE to every trust boundary crossing and data flow in your system: S poofing (authentication), T ampering (integrity), R epudiation (audit logging), I nformation Disclosure (encryption), D enial of Service (rate limiting), E levation of Privilege (authorization). Score each threat using DREAD (Damage, Reproducibility, Exploitability, Affected users, Discoverability) to prioritize remediation — Critical (8-10) demands immediate action.
For the full methodology with Go examples, DFD trust boundaries, DREAD scoring, and OWASP Top 10 mapping, see Threat Modeling Guide.
SeverityVulnerabilityDefenseStandard Library SolutionCriticalSQL InjectionParameterized queries separate data from codedatabase/sql with ? placeholdersCriticalCommand InjectionPass args separately, never via shell concatenationexec.Command with separate argsHighXSSAuto-escaping renders user data as text, not HTML/JShtml/template, text/templateHighPath TraversalScope untrusted file access to an allowed rootGo 1.24+: use os.Root. Pre-Go 1.24: use filepath.IsLocal + filepath.Rel + separator-aware checks; never rely on filepath.Clean + strings.HasPrefix alone.MediumTiming AttacksConstant-time comparison avoids byte-by-byte leakscrypto/subtle.ConstantTimeCompareHighCrypto IssuesUse vetted algorithms; never roll your owncrypto/aes, crypto/randMediumHTTP SecurityTLS + security headers prevent downgrade attacksnet/http, configure TLSConfigLowMissing HeadersHSTS, CSP, X-Frame-Options prevent browser attacksSecurity headers middlewareMediumRate LimitingRate limits prevent brute-force and resource exhaustiongolang.org/x/time/rate, server timeoutsHighRace ConditionsProtect shared state to prevent data corruptionsync.Mutex, channels, avoid shared state
For complete examples, code snippets, and CWE mappings, see:
unsafe usage.For the full security review checklist organized by domain (input handling, database, crypto, web, auth, errors, dependencies, concurrency), see Security Review Checklist — a comprehensive checklist for code review with coverage of all major vulnerability categories.
Security-relevant linters: bodyclose, sqlclosecheck, nilerr, errcheck, govet, staticcheck. See the samber/cc-skills-golang@golang-lint skill for configuration and usage.
For deeper security-specific analysis:
bash
# Go security checker (SAST)
go get -tool github.com/securego/gosec/v2/cmd/gosec@latest
go tool gosec ./...
# Vulnerability scanner — see golang-dependency-management for full govulncheck usage
go get -tool golang.org/x/vuln/cmd/govulncheck@latest
go tool govulncheck ./...
To check the known CVEs of a specific module or version without scanning the whole tree (e.g. when vetting a dependency on pkg.go.dev), → See samber/cc-skills-golang@golang-pkg-go-dev skill.
bash
# Race detector
go test -race ./...
# Fuzz testing
go test -fuzz=Fuzz
SeverityMistakeFixHighmath/rand for tokensOutput is predictable — attacker can reproduce the sequence. Use crypto/randCriticalSQL string concatenationAttacker can modify query logic. Parameterized queries keep data and code separateCriticalexec.Command("bash -c")Shell interprets metacharacters ( ;, |, `). Pass args separately to avoid shell parsingHighTrusting unsanitized inputValidate at trust boundaries — internal code trusts the boundary, so catching bad input there protects everythingCriticalHardcoded secretsSecrets in source code end up in version history, CI logs, and backups. Use env vars or secret managersMediumComparing secrets with ==``== short-circuits on first differing byte, leaking timing info. Use crypto/subtle.ConstantTimeCompareMediumReturning detailed errorsStack traces and DB errors help attackers map your system. Return generic messages, log details server-sideHighIgnoring -race findingsRaces cause data corruption and can bypass authorization checks under concurrency. Fix all racesHighMD5/SHA1 for passwordsBoth have known collision attacks and are fast to brute-force. Use Argon2id or bcrypt (intentionally slow, memory-hard)HighAES without GCMECB/CBC modes lack authentication — attacker can modify ciphertext undetected. GCM provides encrypt+authenticateMediumBinding to 0.0.0.0Exposes service to all network interfaces. Bind to specific interface to limit attack surface
SeverityAnti-PatternWhy It FailsFixHighSecurity through obscurityHidden URLs are discoverable via fuzzing, logs, or sourceAuthentication + authorization on all endpointsHighTrusting client headersX-Forwarded-For, X-Is-Admin are trivially forgedServer-side identity verificationHighClient-side authorizationJavaScript checks are bypassed by any HTTP clientServer-side permission checks on every handlerHighShared secrets across envsStaging breach compromises productionPer-environment secrets via secret managerCriticalIgnoring crypto errors_, _ = encrypt(data) silently proceeds unencryptedAlways check errors — fail closed, never openCriticalRolling your own cryptoCustom encryption hasn't been analyzed by cryptographersUse crypto/aes GCM, golang.org/x/crypto/argon2
See Security Architecture for detailed anti-patterns with Go code examples.
See samber/cc-skills-golang@golang-database, samber/cc-skills-golang@golang-safety, samber/cc-skills-golang@golang-observability, samber/cc-skills-golang@golang-continuous-integration skills.
samber/cc-skills-golang@golang-continuous-integration skill for automated AI-driven code review in CI using these guidelines