agentleFS
johnqtcgjohnqtcg/awesome-skills/skills/go-security-review/SKILL.md

go-security-review

Skill30 starsChanged 4 months agoMITView on GitHub

Review Go code for security vulnerabilities including OWASP Top 10, injection, auth/authz, crypto, secrets, SSRF, XSS, and input validation. Trigger when code involves SQL, user input, authentication, HTTP handlers, TLS, crypto, secrets, or file path operations. Use for security-focused code review of Go projects.

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. About 0 are common, 8 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈8

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Never claim gosec or any security tool ran unless it actually produced output.

    line 33
  2. Very specific:

    Read go.mod for the go directive.

    line 36
  3. Distinctive:

    Before reporting, verify finding is not a false positive.

    line 39
  4. Very specific:

    Speculative injection when input is internal/constant: Do NOT flag fmt.Sprintf in SQL when the interpolated value is a compile-time …

    line 42
  5. Distinctive:

    Over-cautious crypto on non-password use: Do NOT flag MD5/SHA1 for cache key derivation, content hashing, or checksums where collision …

    line 43
  6. Distinctive:

    Context over-propagation: Do NOT flag "missing context.Context" when function is synchronous, short-lived, no I/O, no cancellable work.

    line 44
  7. Distinctive:

    Rate limiting on internal-only endpoints: Do NOT flag rate limiting absence on endpoints not exposed to public traffic (internal mesh, …

    line 45
  8. Distinctive:

    Insufficient evidence rule: Every finding must quote concrete code evidence.

    line 46
  9. Distinctive:

    Run grep for all grep-gated checklist items against target files

    line 65
  10. Distinctive:

    All High severity unless marked (Medium).

    line 84
  11. Very specific:

    Every finding: exact location (path:line), concrete impact, actionable fix with code example

    line 112
  12. Distinctive:

    No speculative findings — require evidence of user-controlled input reaching the vulnerable path

    line 114
  13. Very specific:

    If no issues found: state No security findings identified.

    line 173

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Go Security Review

Purpose

Identify exploitable security vulnerabilities in Go code. Scope is strictly security: injection, authentication/authorization, cryptography, secrets management, input validation, transport security, and HTTP hardening.

This skill does NOT cover: performance, concurrency (race conditions), code quality/style, test quality, error handling patterns, or business logic correctness — those belong to sibling vertical skills.

When To Use

  • Code touches SQL queries, command execution, or file path operations
  • Code handles user input, authentication, authorization, or session management
  • Code involves HTTP handlers, TLS configuration, or cryptographic operations
  • Code contains hardcoded string literals that may be secrets
  • Security-focused PR review requested

When NOT To Use

  • Performance optimization → go-performance-review
  • Concurrency/race conditions → go-concurrency-review
  • Error handling correctness → go-error-review
  • Code style/lint → go-quality-review
  • Test quality → go-test-review
  • Business logic correctness → go-logic-review

Mandatory Gates

1) Execution Integrity Gate

Never claim gosec or any security tool ran unless it actually produced output. If not run: state reason + exact command.

2) Go Version Gate

Read go.mod for the go directive. Do NOT recommend version-specific features above project version. If inaccessible, record Go version: unknown.

3) Anti-Example Suppression Gate

Before reporting, verify finding is not a false positive. MUST quote specific code evidence satisfying the precondition. Category match alone is insufficient.

Embedded anti-examples for security domain:

  • Speculative injection when input is internal/constant: Do NOT flag fmt.Sprintf in SQL when the interpolated value is a compile-time constant, config value, or internal enum. Trace data flow from input source to dangerous function — confirm user input actually reaches it.
  • Over-cautious crypto on non-password use: Do NOT flag MD5/SHA1 for cache key derivation, content hashing, or checksums where collision resistance is not a security requirement. Flag ONLY for password hashing, auth tokens, or integrity verification of untrusted data.
  • Context over-propagation: Do NOT flag "missing context.Context" when function is synchronous, short-lived, no I/O, no cancellable work.
  • Rate limiting on internal-only endpoints: Do NOT flag rate limiting absence on endpoints not exposed to public traffic (internal mesh, admin behind VPN). Verify endpoint exposure before reporting.
  • Insufficient evidence rule: Every finding must quote concrete code evidence. "This endpoint handles user input" is not sufficient — show the path from input to dangerous function.

4) Generated Code Exclusion Gate

Exclude: *.pb.go, *_gen.go, mock_*.go, wire_gen.go, *_string.go, files with // Code generated .* DO NOT EDIT. Note excluded files in Execution Status.

Workflow

  1. Define scope — confirm files/diff under review. Apply Generated Code Exclusion Gate.
  2. Gather evidence — read changed files, identify security-relevant patterns: SQL strings, os/exec, filepath, HTTP handlers, TLS config, crypto, hardcoded literals, auth middleware, URL fetching, template rendering.
  3. Load references — always load go-security-patterns.md; load go-api-http-checklist.md when HTTP/API code present.
  4. Evaluate checklist — execute ALL 16 items. For injection findings, trace data flow from input source to dangerous function.
  5. Apply suppression — run candidates through anti-example gate → format output.

Grep-Gated Execution Protocol

This skill uses mechanical grep pre-scanning to guarantee zero missed checklist items. 14 of 16 items are grep-gated; 2 are semantic-only.

Execution Order

  1. Identify target files (from dispatch prompt, or write raw snippet to $TMPDIR/review_snippet.go)
  2. Run grep for all grep-gated checklist items against target files
  3. HIT → run semantic analysis to confirm or reject (trace data flow for injection findings)
  4. MISS → auto-mark NOT FOUND, skip semantic analysis
  5. For compound patterns: run primary grep, then secondary pattern, apply AND/AND NOT logic
  6. For semantic-only items (items 9, 12): full model reasoning
  7. Report only FOUND items

Grep Audit Line

Include in Execution Status: Grep pre-scan: X/14 items hit, Z confirmed as findings (2 semantic-only)

Compound Pattern Protocol

  • Item 3 (Path traversal): filepath\.Join\|os\.Open HIT → trace whether input comes from user request
  • Item 8 (Sensitive data in logs): log\.\|slog\. HIT → check if logged value includes password/token/PII
  • Item 10 (SSRF): http\.Get\|client\.Do HIT → trace whether URL comes from user input
  • Item 15 (Timing attack): secret comparison HIT AND subtle.ConstantTimeCompare NOT found
  • Item 16 (Input validation): Atoi\|ParseInt HIT → check if result used for allocation/slice sizing without bounds check

Security Checklist (16 Items)

All High severity unless marked (Medium).

#ItemCode Pattern TriggersGrep Pattern
1SQL injectionfmt.Sprintf + SQL keywords, string concat in db.Query/db.Exec, gorm.Raw()Sprintf.*SELECT|Sprintf.*INSERT|Sprintf.*UPDATE|Sprintf.*DELETE|db\.Query|db\.Exec|gorm\.Raw
2Command injectionos/exec with variables from request/config, sh -c with interpolationos/exec|exec\.Command
3Path traversalfilepath.Join with unsanitized request input, no filepath.Rel base-dir checkfilepath\.Join|os\.Open|os\.ReadFile (compound: AND user input flows in — semantic required)
4Insecure TLSInsecureSkipVerify: true, MinVersion below TLS 1.2InsecureSkipVerify|MinVersion|tls\.Config
5Weak cryptomd5.Sum/sha1.Sum for passwords or auth tokens, RSA < 2048, math/rand for secretsmd5\.Sum|sha1\.Sum|math/rand
6Hardcoded secretsString literals matching sk-, ghp_, AKIA, password=, -----BEGINsk-|ghp_|AKIA|password\s*=\s*"|BEGIN.*PRIVATE
7unsafe packageimport "unsafe" without documented justification comment"unsafe"
8Sensitive data in logsPasswords, tokens, PII in log.*, slog.*, fmt.Errorf, full request body loggedlog\.|slog\.|Errorf|Fprintf (compound: AND sensitive data keyword in same statement — semantic required)
9AuthN/AuthZ flawsJWT without algorithm pinning, IDOR (no ownership check), auth middleware after handlerSemantic-Only (auth/authz patterns require understanding middleware flow)
10SSRFhttp.Get/client.Do with user-controlled URL, no host allowlist or private-IP blockinghttp\.Get|http\.Post|client\.Do|http\.NewRequest (compound: AND user-controlled URL — semantic required)
11XSStext/template for HTML, template.HTML() on user input, fmt.Fprintf to ResponseWriter with HTMLtext/template|template\.HTML|Fprintf.*ResponseWriter
12Rate limiting missing (Medium)Auth/login/password-reset endpoints without rate limit middlewareSemantic-Only (rate limiting detection requires understanding endpoint exposure)
13CORS misconfigurationReflected Origin header, Access-Control-Allow-Origin: * with credentialsAccess-Control|AllowOrigin|CORS|Origin
14HTTP security headers missing (Medium)No X-Content-Type-Options, X-Frame-Options, HSTS, CSPX-Content-Type|X-Frame|Strict-Transport|Content-Security-Policy
15Timing attack== on secrets/tokens instead of crypto/subtle.ConstantTimeCompare==.*secret|==.*token|==.*key|==.*password (compound: AND NOT subtle\.ConstantTimeCompare)
16Input validation missingNo http.MaxBytesReader on body, unchecked strconv.Atoi used for allocation sizeMaxBytesReader|LimitReader|Atoi|ParseInt|ParseUint

Severity Rubric

High — Exploitable vulnerability: injection, auth bypass, data exposure, SSRF, hardcoded secrets, insecure TLS.

Medium — Requires specific conditions or defense-in-depth gap: missing headers, rate limiting, weak config defaults.

Evidence Rules

  • Every finding: exact location (path:line), concrete impact, actionable fix with code example
  • For injection: trace data flow — name the source (e.g., r.URL.Query().Get("q") at handler.go:23) and the sink (e.g., fmt.Sprintf at repo.go:67)
  • No speculative findings — require evidence of user-controlled input reaching the vulnerable path
  • Merge rule: same issue at ≥3 locations → one finding with location list

Output Format

Findings

[High|Medium] Short Title

  • ID: SEC-NNN
  • Location: path:line (or location list)
  • Impact: What an attacker could achieve
  • Evidence: Concrete code path showing the vulnerability
  • Recommendation: Specific fix with code example
  • Action: must-fix | follow-up

Suppressed Items

[Suppressed] Short Title

  • Reason: Anti-example matched + specific evidence cited
  • Residual risk: Brief note

Execution Status

  • Go version: X.Y or unknown
  • gosec: PASS | FAIL | Not available (reason + command)
  • Grep pre-scan: X/14 items hit, Z confirmed as findings (2 semantic-only)
  • Excluded (generated): list or None
  • References loaded: list

Summary

1-2 lines. Count by severity.

Example Output

### Findings

#### [High] SQL Injection in User Search
- **ID:** SEC-001
- **Location:** `internal/repo/user.go:67`
- **Impact:** Attacker can execute arbitrary SQL via search parameter
- **Evidence:** `fmt.Sprintf("SELECT * FROM users WHERE name LIKE '%%%s%%'", name)` — `name` flows from `r.URL.Query().Get("q")` at handler.go:23 through SearchUsers() without sanitization
- **Recommendation:** Use parameterized query: `db.QueryContext(ctx, "SELECT * FROM users WHERE name LIKE ?", "%"+name+"%")`
- **Action:** must-fix

### Suppressed Items
#### [Suppressed] MD5 Usage in Cache Key Generation
- **Reason:** MD5 at cache.go:15 is used for cache key derivation from internal struct, not password hashing. Anti-example: "over-cautious crypto on non-password use"
- **Residual risk:** None — cache key collision is acceptable

### Execution Status
- Go version: 1.21
- gosec: Not available (command: `gosec ./...`)
- Grep pre-scan: 3/14 items hit, 1 confirmed as findings (2 semantic-only)
- Excluded (generated): None
- References loaded: go-security-patterns.md, go-api-http-checklist.md

### Summary
1 High finding (SQL injection). No Medium findings.

No-Finding Case

If no issues found: state No security findings identified. Still output Execution Status, Suppressed Items (if any), Summary.

Load References Selectively

ReferenceLoad When
references/go-security-patterns.mdAlways
references/go-api-http-checklist.mdCode involves net/http, handlers, gin/echo/chi, gRPC, middleware
references/go-review-anti-examples.mdAlways

Review Discipline

  • Security only — never comment on performance, concurrency, style, tests, error handling, or logic
  • Execute ALL 16 checklist items — do not skip because others produced High findings
  • Trace data flow for every injection finding — name source and sink
  • Prefer precision over volume — one well-evidenced finding beats five speculative warnings

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.