Skilllibrary security-hardening
Apply OWASP Top 10 mitigations as concrete grep-able patterns and code fixes during development and review. Trigger on "harden application", "OWASP review", "security controls", "injection prevention", "XSS prevention", or security audit response. Do not use for security-best-practices (language-specific secure coding guidance), security-threat-model (threat enumeration and abuse paths), or auth-patterns (authentication/authorization implementation).
git clone https://github.com/merceralex397-collab/skilllibrary
T=$(mktemp -d) && git clone --depth=1 https://github.com/merceralex397-collab/skilllibrary "$T" && mkdir -p ~/.claude/skills && cp -r "$T/02-generated-repo-core/security-hardening" ~/.claude/skills/merceralex397-collab-skilllibrary-security-hardening && rm -rf "$T"
02-generated-repo-core/security-hardening/SKILL.mdPurpose
Apply OWASP Top 10 mitigations to code during development and review. Each vulnerability class has specific, checkable defenses—not vague "be careful" advice. This skill translates threat categories into grep-able patterns and concrete fixes.
When to use this skill
Use when:
- Code review with security focus
- Hardening existing application before launch
- Adding security controls to new feature
- Responding to security audit findings
Do NOT use when:
- Full penetration testing needed (hire specialists)
- Compliance audit (use compliance-specific checklists)
- Infrastructure security (different skill set)
Operating procedure
-
A01:2021 - Broken Access Control (most critical):
# ❌ Direct object reference without authorization check @app.get("/users/{user_id}/data") def get_user_data(user_id: int): return db.get_user_data(user_id) # Anyone can access any user! # ✅ Verify authorization @app.get("/users/{user_id}/data") def get_user_data(user_id: int, current_user: User = Depends(get_current_user)): if current_user.id != user_id and not current_user.is_admin: raise HTTPException(403, "Not authorized") return db.get_user_data(user_id) -
A02:2021 - Cryptographic Failures:
# ❌ Weak hashing password_hash = hashlib.md5(password.encode()).hexdigest() # ✅ Use bcrypt/argon2 for passwords from passlib.hash import argon2 password_hash = argon2.hash(password) # ❌ Hardcoded secrets API_KEY = "sk-1234567890" # ✅ Environment variables API_KEY = os.environ["API_KEY"] -
A03:2021 - Injection (SQL, Command, LDAP):
# ❌ SQL injection query = f"SELECT * FROM users WHERE email = '{email}'" # ✅ Parameterized queries query = "SELECT * FROM users WHERE email = %s" cursor.execute(query, (email,)) # ❌ Command injection os.system(f"convert {user_filename} output.png") # ✅ Use subprocess with list arguments subprocess.run(["convert", user_filename, "output.png"], check=True) -
A04:2021 - Insecure Design (architecture level):
# ❌ No rate limiting on sensitive endpoints @app.post("/login") def login(credentials: Credentials): return authenticate(credentials) # ✅ Rate limit authentication attempts from slowapi import Limiter limiter = Limiter(key_func=get_remote_address) @app.post("/login") @limiter.limit("5/minute") def login(credentials: Credentials): return authenticate(credentials) -
A05:2021 - Security Misconfiguration:
# ❌ Debug mode in production app.run(debug=True) # ✅ Environment-based configuration app.run(debug=os.environ.get("ENV") == "development") # ❌ Default credentials ADMIN_PASSWORD = "admin" # ✅ Require configuration ADMIN_PASSWORD = os.environ["ADMIN_PASSWORD"] if not ADMIN_PASSWORD: raise RuntimeError("ADMIN_PASSWORD must be set") -
A07:2021 - Cross-Site Scripting (XSS):
<!-- ❌ Unescaped user content --> <div>{{ user_input | safe }}</div> <!-- ✅ Auto-escaped (default in most frameworks) --> <div>{{ user_input }}</div> <!-- ✅ Content Security Policy header --> Content-Security-Policy: default-src 'self'; script-src 'self' -
Quick security grep patterns:
# Find potential SQL injection grep -rn "f\"SELECT\|f'SELECT\|\.format.*SELECT" --include="*.py" # Find hardcoded secrets grep -rn "password\s*=\s*['\"]" --include="*.py" grep -rn "api_key\s*=\s*['\"]" --include="*.py" # Find dangerous functions grep -rn "eval(\|exec(\|os\.system(" --include="*.py" grep -rn "shell=True" --include="*.py" # Find missing auth decorators grep -rn "@app\.\(get\|post\|put\|delete\)" --include="*.py" | grep -v "@requires_auth"
Output defaults
## Security Review: [Component/Feature] ### Findings | ID | Category | Severity | Location | Issue | Fix | |----|----------|----------|----------|-------|-----| | 1 | A03 Injection | High | api/users.py:45 | SQL string formatting | Use parameterized query | | 2 | A01 Access Control | Medium | api/orders.py:23 | Missing ownership check | Add user_id verification | ### Mitigations Applied - [ ] Input validation on all endpoints - [ ] Parameterized queries for all DB access - [ ] Authorization checks on resource access - [ ] Rate limiting on auth endpoints - [ ] Security headers configured ### Headers to Set
Content-Security-Policy: default-src 'self' X-Content-Type-Options: nosniff X-Frame-Options: DENY Strict-Transport-Security: max-age=31536000; includeSubDomains
References
Failure handling
- Finding too many issues: Prioritize by exploitability and impact; fix critical auth/injection first
- Can't fix without major refactor: Document as tech debt with risk assessment; add compensating controls
- Third-party library vulnerable: Check if newer version available; if not, evaluate alternatives or add wrapper validation
- Security vs. usability conflict: Document the tradeoff explicitly; get business decision rather than silently accepting risk
- Not sure if issue is exploitable: Assume it is; fix it anyway—defense in depth