| name | security-audit |
| description | Triggers for authentication, payments, user input, and API endpoints to check OWASP risks. Auto-evaluates security need and provides actionable fixes, not checklists. |
Security Audit Skill
Purpose: Catch security vulnerabilities early with targeted checks, not generic checklists.
Trigger Words: auth, login, password, payment, credit card, token, API endpoint, user input, SQL, database query, session, cookie, upload
Quick Decision: When to Audit?
def needs_security_audit(code_context: dict) -> bool:
"""Fast security risk evaluation."""
# ALWAYS audit these (high risk)
critical_patterns = [
"authentication", "authorization", "login", "password",
"payment", "credit card", "billing", "stripe", "paypal",
"admin", "sudo", "privilege", "role",
"token", "jwt", "session", "cookie",
"sql", "database", "query", "exec", "eval",
"upload", "file", "download", "path traversal"
]
# Check if any critical pattern in code
if any(p in code_context.get("description", "").lower() for p in critical_patterns):
return True
# Skip for: docs, tests, config, low-risk utils
skip_patterns = ["test_", "docs/", "README", "config", "utils"]
if any(p in code_context.get("files", []) for p in skip_patterns):
return False
return False
Security Checks (Targeted, Not Exhaustive)
1. Input Validation (Most Common)
# ❌ BAD - No validation
def get_user(user_id):
return db.query(f"SELECT * FROM users WHERE id = {user_id}")
# ✅ GOOD - Validated + parameterized
def get_user(user_id: int):
if not isinstance(user_id, int) or user_id <= 0:
raise ValueError("Invalid user_id")
return db.query("SELECT * FROM users WHERE id = ?", [user_id])
Quick Fix: Add type hints + validation at entry points.
2. SQL Injection (Critical)
# ❌ BAD - String interpolation
query = f"SELECT * FROM users WHERE email = '{email}'"
# ✅ GOOD - Parameterized queries
query = "SELECT * FROM users WHERE email = ?"
db.execute(query, [email])
Quick Fix: Never use f-strings for SQL. Use ORM or parameterized queries.
3. Authentication & Secrets (Critical)
# ❌ BAD - Hardcoded secrets
API_KEY = "sk_live_abc123"
password = "admin123"
# ✅ GOOD - Environment variables
API_KEY = os.getenv("STRIPE_API_KEY")
# Passwords: bcrypt hashed, never plaintext
# ❌ BAD - Weak session
session["user_id"] = user_id # No expiry, no signing
# ✅ GOOD - Secure session
session.permanent = False
session["user_id"] = user_id
session["expires"] = time.time() + 3600 # 1 hour
Quick Fix: Extract secrets to .env, hash passwords, add session expiry.
4. Authorization (Often Forgotten)
# ❌ BAD - Missing authorization check
@app.route("/admin/users/<user_id>", methods=["DELETE"])
def delete_user(user_id):
User.delete(user_id) # Anyone can delete!
# ✅ GOOD - Check permissions
@app.route("/admin/users/<user_id>", methods=["DELETE"])
@require_role("admin")
def delete_user(user_id):
if not current_user.can_delete(user_id):
abort(403)
User.delete(user_id)
Quick Fix: Add permission checks before destructive operations.
5. Rate Limiting (API Endpoints)
# ❌ BAD - No rate limit
@app.route("/api/login", methods=["POST"])
def login():
# Brute force possible
return authenticate(request.json)
# ✅ GOOD - Rate limited
@app.route("/api/login", methods=["POST"])
@rate_limit("5 per minute")
def login():
return authenticate(request.json)
Quick Fix: Add rate limiting to login, payment, sensitive endpoints.
6. XSS Prevention (Frontend/Templates)
# ❌ BAD - Unescaped user input
return f"<div>Welcome {username}</div>" # XSS if username = "<script>alert('XSS')</script>"
# ✅ GOOD - Escaped output
from html import escape
return f"<div>Welcome {escape(username)}</div>"
# Or use framework escaping (Jinja2, React auto-escapes)
Quick Fix: Escape user input in HTML. Use framework defaults.
7. File Upload Safety
# ❌ BAD - No validation
@app.route("/upload", methods=["POST"])
def upload():
file = request.files["file"]
file.save(f"uploads/{file.filename}") # Path traversal! Overwrite!
# ✅ GOOD - Validated
import os
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = {"png", "jpg", "pdf"}
@app.route("/upload", methods=["POST"])
def upload():
file = request.files["file"]
if not file or "." not in file.filename:
abort(400, "Invalid file")
ext = file.filename.rsplit(".", 1)[1].lower()
if ext not in ALLOWED_EXTENSIONS:
abort(400, "File type not allowed")
filename = secure_filename(file.filename)
file.save(os.path.join("uploads", filename))
Quick Fix: Whitelist extensions, sanitize filenames, limit size.
Output Format (Actionable Only)
## Security Audit Results
**Risk Level**: [CRITICAL | HIGH | MEDIUM | LOW]
### Issues Found: X
1. **[CRITICAL] SQL Injection in get_user() (auth.py:45)**
- Issue: f-string used for SQL query
- Fix: Use parameterized query
- Code:
```python
# Change this:
query = f"SELECT * FROM users WHERE id = {user_id}"
# To this:
query = "SELECT * FROM users WHERE id = ?"
db.execute(query, [user_id])
```
2. **[HIGH] Missing rate limiting on /api/login**
- Issue: Brute force attacks possible
- Fix: Add @rate_limit("5 per minute") decorator
3. **[MEDIUM] Hardcoded API key in config.py:12**
- Issue: Secret in code
- Fix: Move to environment variable
---
**Next Steps**:
1. Fix CRITICAL issues first (SQL injection)
2. Add rate limiting (5 min fix)
3. Extract secrets to .env
4. Re-run security audit after fixes
Integration with Workflow
# Automatic trigger
/lazy code "add user login endpoint"
→ security-audit triggers
→ Checks: password handling, session, rate limiting
→ Finds: Missing bcrypt hash, no rate limit
→ Suggests fixes with code examples
→ Developer applies fixes
→ Re-audit confirms: ✅ Secure
# Manual trigger
Skill(command="security-audit")
What This Skill Does NOT Do
❌ Generate 50-item security checklists (not actionable) ❌ Flag every minor issue (noise) ❌ Require penetration testing (that's a different tool) ❌ Cover infrastructure security (AWS, Docker, etc.)
✅ DOES: Catch common code-level vulnerabilities with fast, practical fixes.
Configuration
# Strict mode: audit everything (slower)
export LAZYDEV_SECURITY_STRICT=1
# Disable security skill
export LAZYDEV_DISABLE_SECURITY=1
# Focus on specific risks only
export LAZYDEV_SECURITY_FOCUS="sql,auth,xss"
Version: 1.0.0 OWASP Coverage: SQL Injection, XSS, Broken Auth, Insecure Design, Security Misconfiguration Speed: <5 seconds for typical file