rules: # ── Go: HTTP handler context hygiene ──────────────────────────────────────── - id: veylant-context-background-in-handler languages: [go] severity: WARNING message: > HTTP handler uses context.Background() instead of r.Context(). This bypasses request cancellation, tracing, and tenant context propagation. Use r.Context() to inherit the request lifetime. patterns: - pattern: | func $HANDLER($W http.ResponseWriter, $R *http.Request) { ... context.Background() ... } paths: include: - "internal/**/*.go" - "cmd/**/*.go" # ── Go: SQL injection risk ────────────────────────────────────────────────── - id: veylant-sql-string-concatenation languages: [go] severity: ERROR message: > SQL query built using string concatenation or fmt.Sprintf. This is a potential SQL injection vulnerability. Use parameterised queries ($1, $2, ...) or named placeholders instead. patterns: - pattern: db.QueryContext($CTX, $QUERY + $VAR, ...) - pattern: db.QueryRowContext($CTX, $QUERY + $VAR, ...) - pattern: db.ExecContext($CTX, $QUERY + $VAR, ...) - pattern: db.QueryContext($CTX, fmt.Sprintf(...), ...) - pattern: db.QueryRowContext($CTX, fmt.Sprintf(...), ...) - pattern: db.ExecContext($CTX, fmt.Sprintf(...), ...) paths: include: - "internal/**/*.go" # ── Go: Sensitive data in structured logs ─────────────────────────────────── - id: veylant-sensitive-field-in-log languages: [go] severity: WARNING message: > Potentially sensitive field name logged. Ensure this does not contain PII, API keys, passwords, or tokens. Use redaction helpers for sensitive values. patterns: - pattern: zap.String("password", ...) - pattern: zap.String("api_key", ...) - pattern: zap.String("token", ...) - pattern: zap.String("secret", ...) - pattern: zap.String("Authorization", ...) - pattern: zap.String("email", ...) - pattern: zap.String("prompt", ...) paths: include: - "internal/**/*.go" - "cmd/**/*.go" # ── Go: Hardcoded credentials ─────────────────────────────────────────────── - id: veylant-hardcoded-api-key languages: [go] severity: ERROR message: > Hardcoded string that looks like an API key or secret. API keys must be loaded from environment variables or Vault — never hardcoded. patterns: - pattern: | $KEY = "sk-..." - pattern: | APIKey: "sk-..." paths: include: - "internal/**/*.go" - "cmd/**/*.go" # ── Go: Missing request size limit ───────────────────────────────────────── - id: veylant-missing-max-bytes-reader languages: [go] severity: WARNING message: > HTTP request body decoded without http.MaxBytesReader(). A client can send an unbounded body, causing memory exhaustion. Wrap r.Body with http.MaxBytesReader(w, r.Body, maxBytes) before decoding. patterns: - pattern: json.NewDecoder($R.Body).Decode(...) paths: include: - "internal/**/*.go" fix: | r.Body = http.MaxBytesReader(w, r.Body, 1<<20) // 1 MiB json.NewDecoder(r.Body).Decode(...) # ── Python: Eval/exec of user input ───────────────────────────────────────── - id: veylant-python-eval-user-input languages: [python] severity: ERROR message: > eval() or exec() called with a variable — potential code injection. Never evaluate user-supplied data. patterns: - pattern: eval($X) - pattern: exec($X) paths: include: - "services/**/*.py"