Triggers for authentication, payments, user input, and API endpoints to check OWASP risks. Auto-evaluates security need and provides actionable fixes, not checklists.
Automatically detects OWASP security risks in authentication, payments, and API endpoints. Triggers on keywords like "login", "payment", or "SQL" to provide targeted fixes instead of generic checklists.
/plugin marketplace add MacroMan5/claude-code-workflow-plugins/plugin install lazy@lazy-dev-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
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
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
# ❌ 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.
# ❌ 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.
# ❌ 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.
# ❌ 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.
# ❌ 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.
# ❌ 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.
# ❌ 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.
## 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
# 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")
❌ 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.
# 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