Auth, input-validation, and secrets conventions. Use when writing or reviewing authentication, authorization, middleware, routes, JWT, CSRF, or CORS code; for a full audit of pending changes use /security-review.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add edjchapman/claude-code-config --skill security-patterns --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Security Patterns?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/edjchapman-security-patterns)More formats (shields.io, HTML) on the badges page.
---
name: security-patterns
description: Auth, input-validation, and secrets conventions. Use when writing or reviewing authentication, authorization, middleware, routes, JWT, CSRF, or CORS code; for a full audit of pending changes use /security-review.
---
# Security Patterns
Apply these security practices when writing or reviewing code in auth, middleware, and API layers.
## Input Validation
- **Always validate** at system boundaries (API endpoints, form handlers, message consumers)
- **Never trust** client-side validation alone
- Use allowlists over denylists for input filtering
- Validate types, lengths, ranges, and formats
- Sanitize HTML output to prevent XSS (use framework auto-escaping)
## SQL Injection Prevention
- **Always** use parameterized queries or ORM methods
- **Never** construct SQL with string concatenation or f-strings
- Django: use QuerySet methods, `Q` objects, or `params` argument for raw SQL
- Node.js: use query builders (Knex) or ORM (Prisma, TypeORM) -- never template literals in SQL
```python
# WRONG
User.objects.raw(f"SELECT * FROM users WHERE email = '{email}'")
# CORRECT
User.objects.raw("SELECT * FROM users WHERE email = %s", [email])
User.objects.filter(email=email)
```
## Authentication
- Hash passwords with bcrypt, argon2, or scrypt (never MD5/SHA alone)
- Enforce minimum password complexity at registration
- Rate-limit login attempts (exponential backoff or account lockout)
- Use constant-time comparison for tokens and secrets
- Invalidate sessions on password change
## JWT / Token Security
- Set short expiration times (15min for access tokens, days for refresh)
- Store refresh tokens server-side (database or Redis)
- Never store sensitive data in JWT payload (it's base64, not encrypted)
- Validate `iss`, `aud`, and `exp` claims on every request
- Use `RS256` or `ES256` over `HS256` for multi-service architectures
## CSRF Protection
- Enable framework CSRF middleware (Django: `CsrfViewMiddleware`)
- Use `SameSite=Lax` or `Strict` on session cookies
- For SPAs: use token-based auth or double-submit cookies
- Never disable CSRF protection for convenience
## Authorization
- Check permissions on every request, not just in UI
- Use role-based or attribute-based access control
- Verify object ownership: `if obj.owner != request.user: return 403`
- Log authorization failures for monitoring
## Secrets Management
- Never hardcode secrets, API keys, or passwords in code
- Use environment variables or secret managers (AWS Secrets Manager, Vault)
- Add `.env` and credential files to `.gitignore`
- Rotate secrets on schedule and after any suspected breach
## HTTP Security Headers
Ensure these headers are set in production:
- `Strict-Transport-Security: max-age=31536000; includeSubDomains`
- `Content-Security-Policy: default-src 'self'`
- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: DENY`
- `Referrer-Policy: strict-origin-when-cross-origin`
## Logging
- Log authentication events (login, logout, failed attempts)
- Log authorization failures
- **Never log** passwords, tokens, API keys, or PII
- Include request IDs for traceability
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!