Go security
Skill hlsitechio/claude-skills-security/appsec-stack-pack/go-security
Defensive security audit skills for Claude — tech-stack-keyed and audit-domain-keyed packs for SaaS apps.
npx -y skills add hlsitechio/claude-skills-security --skill go-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Security audit for Go applications including net/http servers, Gin/Echo/Chi/Fiber frameworks, database/sql injection patterns, template auto-escape, context propagation, goroutine race conditions, file path handling with filepath.Join, and Go-specific patterns. Use this skill whenever the user mentions Go, golang, net/http, Gin, gin-gonic, Echo, labstack/echo, Chi, go-chi, Fiber, gofiber, database/sql, sqlx, GORM, html/template, or asks "audit my Go app", "Go security review", "gosec". Trigger when the codebase contains `go.mod`, `*.go` files, or Go in the deployment.
SKILL.md
7.1 KB, as published. Nobody here has run it
Go Security Audit
Audit Go applications across stdlib net/http, Gin, Echo, Chi, Fiber.
When this skill applies
- Reviewing Go HTTP handlers and middleware
- Auditing database queries (database/sql, sqlx, GORM)
- Reviewing template usage (html/template vs text/template)
- Checking goroutine safety and context propagation
- Reviewing file path handling
Workflow
Follow ../_shared/audit-workflow.md.
Phase 1: Stack detection
grep -E '^module|require' go.mod | head
# Detect framework
grep -E 'github.com/(gin-gonic/gin|labstack/echo|go-chi/chi|gofiber/fiber|valyala/fasthttp)' go.mod
Phase 2: Inventory
# Handlers and routes
grep -rn 'http\.HandleFunc\|r\.GET\|r\.POST\|router\.\|app\.' --include='*.go' . | head -50
# SQL queries
grep -rn 'db\.Query\|db\.QueryRow\|db\.Exec\|Prepare' --include='*.go' .
# Templates
grep -rn 'text/template\|html/template' --include='*.go' .
# File paths
grep -rn 'os\.Open\|filepath\.Join\|filepath\.Clean' --include='*.go' .
# Cryptography
grep -rn 'crypto/md5\|crypto/sha1\|crypto/des' --include='*.go' .
Phase 3: Detection — the checks
Template injection
- GOL-TPL-1
html/templateused for HTML output (auto-escapes); nevertext/templatefor HTML (no escaping).// BAD — text/template doesn't escape HTML import "text/template" tmpl, _ := text.Parse("<p>{{.Name}}</p>") // GOOD — html/template context-aware import "html/template" tmpl, _ := html.Parse("<p>{{.Name}}</p>") - GOL-TPL-2 No
template.HTML(userInput),template.JS(userInput),template.URL(userInput)— these mark strings as safe and bypass escaping. - GOL-TPL-3 No
template.Parse(userInput)— SSTI vulnerability.
SQL injection
- GOL-SQL-1
database/sqluses?(MySQL) or$1(Postgres) placeholders:// BAD rows, err := db.Query("SELECT * FROM users WHERE id = " + userID) // GOOD rows, err := db.Query("SELECT * FROM users WHERE id = $1", userID) - GOL-SQL-2
fmt.Sprintfconstructing queries → injection. - GOL-SQL-3 GORM
Raw(sql, args)parameterizes args; string concatenation does not. - GOL-SQL-4 Dynamic ORDER BY / table names → allowlist.
Path traversal
- GOL-PATH-1
filepath.Join(root, userInput)does NOT prevent..traversal. After Join, verify result stays under root:safeRoot, _ := filepath.Abs("/var/data/userfiles") target := filepath.Join(safeRoot, filepath.Clean(userInput)) resolved, err := filepath.Abs(target) if err != nil || !strings.HasPrefix(resolved, safeRoot+string(filepath.Separator)) { return errForbidden } - GOL-PATH-2 Archive extraction (zip-slip): check each entry's resolved path stays inside the destination.
CORS
- GOL-COR-1 CORS middleware configured with specific origins. In Gin:
cors.Default()is*; usecors.New(cors.Config{AllowOrigins: [...]}). - GOL-COR-2
AllowCredentials: truecombined withAllowOrigins: ["*"]is rejected by spec but check anyway.
Authentication
- GOL-AUTH-1 JWT validation: parse with explicit signing method; reject
none.token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) { if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method") } return []byte(jwtSecret), nil }) - GOL-AUTH-2 Password hashing:
golang.org/x/crypto/bcryptorargon2id. Not MD5/SHA1/SHA256. - GOL-AUTH-3 Constant-time comparisons:
subtle.ConstantTimeComparefor tokens, MACs.
Authorization
- GOL-AZ-1 Per-handler middleware checks role/permission. Don't rely on URL routing for auth.
- GOL-AZ-2 Ownership check uses values from validated session, not request body.
Middleware order (Gin/Chi/Echo)
- GOL-MW-1 Recovery middleware registered first.
- GOL-MW-2 Security headers (e.g.,
secure.New()) before routes. - GOL-MW-3 CORS before auth (CORS preflight must succeed without auth).
- GOL-MW-4 Rate limiter before expensive parsing/handlers.
File uploads
- GOL-UP-1
r.ParseMultipartForm(maxMemory)with boundedmaxMemory. - GOL-UP-2 File size limited via
http.MaxBytesReader. - GOL-UP-3 Content-type validated by sniffing (
http.DetectContentTypeon bytes), not justheader.Header.Get("Content-Type").
TLS
- GOL-TLS-1 Production servers use
http.Serverwith TLS or terminate TLS at the reverse proxy withStrict-Transport-Securityset. - GOL-TLS-2
tls.Config.MinVersion: tls.VersionTLS12(or 13). - GOL-TLS-3 Custom certificate verification disabled?
tls.Config.InsecureSkipVerify: trueis never OK in production.
Cryptography
- GOL-CRYPTO-1 No
crypto/md5orcrypto/sha1for security purposes (passwords, MACs). - GOL-CRYPTO-2 Random number generation uses
crypto/rand, NOTmath/randfor security tokens. - GOL-CRYPTO-3
crypto/des,crypto/rc4not used.
SSRF
- GOL-SSRF-1
http.Get(userURL)without URL validation → SSRF. Seesaas-security-pack/saas-code-security-review/references/ssrf-patterns.md. - GOL-SSRF-2 Custom
http.ClientwithTransportthat blocks internal IPs.
Goroutine and context
- GOL-CTX-1 Handlers respect
r.Context(); don't spawn goroutines without context for background work tied to request. - GOL-CTX-2 Long-running goroutines started from handlers don't leak (no shutdown signal).
- GOL-CTX-3 Shared maps protected by
sync.Mutexor usesync.Map; concurrent map access without sync is data race + panic.
Error handling
- GOL-ERR-1 Errors not echoed verbatim to clients (
fmt.Fprintln(w, err)leaks internals). - GOL-ERR-2
panicrecovered at handler boundary (gin.Recovery(),chi.Recoverer, custom). - GOL-ERR-3 Stack traces logged server-side only.
Logging
- GOL-LOG-1 No
log.Printf("token=%s", token)— secrets not logged. - GOL-LOG-2 Structured logging (zap, zerolog, slog) with redaction for sensitive fields.
Static analysis
- GOL-SAST-1
gosecrun periodically. Common findings: hardcoded credentials, weak crypto, SQL injection patterns. - GOL-SAST-2
staticcheckandgo vetclean in CI.
Dependencies
- GOL-DEP-1
go.modversions current;go mod tidyclean. - GOL-DEP-2
govulncheckclean — official Go vulnerability scanner.
Phase 4: Triage
Critical: SQL via fmt.Sprintf; tls.InsecureSkipVerify in prod; SSRF reaching internal services; race condition on shared map.
Phase 5: Report
Use ../_shared/findings-schema.md. Prefix IDs with GOL-.