Go Security Checklist
Template Security
- •Use
html/templatepackage (nottext/template) for HTML output - •HTML templates auto-escape content to prevent XSS
- •Never use
text/templatefor web content
Database Security
- •Never use
fmt.Sprintf()to build SQL queries - •Use parameterized queries with database/sql
- •Use prepared statements for repeated queries
- •Apply least privilege to database connections
Cryptographic Randomness
- •Use
crypto/rand(notmath/rand) for security-critical randomness - •Use
crypto/rand.Read()for generating tokens and keys - •Use
crypto/subtle.ConstantTimeCompare()for comparing secrets
TLS/SSL Security
- •Validate certificate chains in TLS connections
- •Don't set
InsecureSkipVerify: truein production - •Use modern TLS versions (TLS 1.2+)
- •Configure strong cipher suites
Input Validation
- •Validate all user input before processing
- •Use
strconvfunctions for type conversion with error checking - •Sanitize input used in system commands or queries
- •Validate file paths to prevent directory traversal
Error Handling
- •Don't expose stack traces or internal errors to users
- •Log detailed errors internally
- •Return generic error messages to clients
- •Use custom error types for better control
Static Analysis Tools
- •Use
gosecfor security-focused static analysis - •Use
go vetto catch common mistakes - •Configure golangci-lint with security linters
- •Run
go mod verifyto check dependencies
Common Vulnerabilities to Prevent
SQL Injection
go
// WRONG - vulnerable to SQL injection
query := fmt.Sprintf("SELECT * FROM users WHERE id = %s", userId)
db.Query(query)
// CORRECT - parameterized query
db.Query("SELECT * FROM users WHERE id = ?", userId)
Path Traversal
go
// WRONG - vulnerable to directory traversal
filepath := "uploads/" + filename
data, _ := os.ReadFile(filepath)
// CORRECT - validate and clean path
import "path/filepath"
base := "/var/www/uploads"
fullpath := filepath.Join(base, filepath.Clean(filename))
if !strings.HasPrefix(fullpath, base) {
return errors.New("invalid path")
}
data, err := os.ReadFile(fullpath)
Command Injection
go
// WRONG - shell injection risk
cmd := exec.Command("sh", "-c", "convert "+userFile+" output.png")
// CORRECT - use array arguments
cmd := exec.Command("convert", userFile, "output.png")
Memory Safety
- •Avoid unsafe package unless absolutely necessary
- •Clear sensitive data from memory after use
- •Use
deferto ensure cleanup happens - •Be careful with slice and map capacities to avoid leaks
Concurrency Safety
- •Protect shared state with mutexes or channels
- •Avoid data races (use
go build -raceto detect) - •Use
sync.Mapfor concurrent map access - •Be careful with goroutine lifecycle management
Dependencies
- •Use
go mod verifyto verify dependencies - •Keep dependencies up to date with
go get -u - •Review security advisories for dependencies
- •Minimize dependency footprint
- •Use
govulncheckto scan for known vulnerabilities