Owasp checklist
Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/owasp-checklist
When to activate: OWASP, security checklist, injection, XSS, IDOR, SSRF, security misconfiguration, vulnerabilityFrom its SKILL.md
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill owasp-checklistAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 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.
SKILL.md
4.7 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
OWASP Top 10 2021 Checklist
A01 — Broken Access Control
# BAD: user can access any order by guessing ID
@app.get("/orders/{order_id}")
def get_order(order_id: int):
return db.query(Order).get(order_id) # no ownership check!
# GOOD: enforce ownership
@app.get("/orders/{order_id}")
def get_order(order_id: int, current_user: User = Depends(get_current_user)):
order = db.query(Order).filter(
Order.id == order_id,
Order.user_id == current_user.id # IDOR prevention
).first()
if not order:
raise HTTPException(status_code=404)
return order
A02 — Cryptographic Failures
# BAD: MD5/SHA1 for passwords, unencrypted PII
import hashlib
hashed = hashlib.md5(password.encode()).hexdigest() # NEVER
# GOOD: bcrypt/argon2
from passlib.hash import argon2
hashed = argon2.hash(password)
verified = argon2.verify(password, hashed)
# Encrypt sensitive fields at rest
from cryptography.fernet import Fernet
key = Fernet.generate_key() # store in secrets manager, not code
cipher = Fernet(key)
encrypted_ssn = cipher.encrypt(ssn.encode())
A03 — Injection
# BAD: SQL injection via f-string
cursor.execute(f"SELECT * FROM users WHERE email = '{email}'")
# GOOD: parameterized query (all ORMs do this by default)
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
# BAD: shell injection
import subprocess
subprocess.run(f"convert {filename} output.pdf", shell=True)
# GOOD: no shell, argument list
subprocess.run(["convert", filename, "output.pdf"], shell=False)
# NoSQL injection prevention
# BAD: MongoDB with user-supplied operator
db.users.find({"password": request.json["password"]})
# If password = {"$ne": ""} → bypasses auth!
# GOOD: validate and cast types
from pydantic import BaseModel
class LoginForm(BaseModel):
email: str
password: str # ensures string, not object
A04 — Insecure Design
- Threat model during design, not after
- Rate-limit sensitive endpoints (login, register, password reset)
- Multi-factor authentication for privileged actions
- Separate admin API from public API
A05 — Security Misconfiguration
# Checklist:
# - Debug mode OFF in production
# - Default credentials changed
# - Unnecessary features disabled
# - Security headers set
# - CORS restricted to known origins
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(CORSMiddleware,
allow_origins=["https://myapp.com"], # NOT "*"
allow_methods=["GET", "POST"],
allow_credentials=True)
# Security headers middleware
@app.middleware("http")
async def security_headers(request, call_next):
response = await call_next(request)
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
response.headers["Strict-Transport-Security"] = "max-age=31536000"
response.headers["Content-Security-Policy"] = "default-src 'self'"
return response
A06 — Vulnerable Components
# Python
pip-audit # audit installed packages
safety check -r requirements.txt
# Node.js
npm audit
npx snyk test
# Docker
trivy image myapp:latest
A07 — Auth Failures
# Rate limiting on login (use slowapi or similar)
from slowapi import Limiter
limiter = Limiter(key_func=get_remote_address)
@app.post("/login")
@limiter.limit("5/minute") # 5 attempts per minute per IP
async def login(form: LoginForm, request: Request): ...
# Account lockout after N failures
# Secure session: httpOnly + secure + sameSite cookies
response.set_cookie("session", token, httponly=True, secure=True, samesite="Strict")
A09 — Logging Failures
# Log security events (never log passwords/tokens)
import logging
logger = logging.getLogger("security")
logger.warning("Failed login attempt", extra={
"email": email, # OK — not sensitive
"ip": request.client.host,
"user_agent": request.headers.get("user-agent")
})
# NEVER: logger.info(f"Login attempt password={password}")
A10 — SSRF
# BAD: fetch user-supplied URL without validation
import httpx
response = httpx.get(user_supplied_url)
# GOOD: allowlist domains
from urllib.parse import urlparse
ALLOWED_HOSTS = {"api.trusted.com", "cdn.trusted.com"}
parsed = urlparse(user_supplied_url)
if parsed.hostname not in ALLOWED_HOSTS:
raise ValueError("URL not allowed")
# Also: bind to non-internal IPs, block 169.254.x.x (AWS metadata)
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.