| name | security-review |
| description | Security vulnerability detection and secure coding practices |
| version | 1.0.0 |
| tags | ["security","vulnerabilities","owasp","secure-coding"] |
Security Review Skill
This skill provides expert knowledge on identifying security vulnerabilities and implementing secure coding practices.
OWASP Top 10 Security Risks
1. Injection Attacks
SQL Injection
query = f"SELECT * FROM users WHERE email = '{user_input}'"
query = "SELECT * FROM users WHERE email = ?"
cursor.execute(query, (user_input,))
Command Injection
os.system(f"ping {user_input}")
import subprocess
subprocess.run(["ping", "-c", "1", validated_host], check=True)
NoSQL Injection
db.users.find({ email: req.body.email })
const email = String(req.body.email);
db.users.find({ email: email })
2. Broken Authentication
Password Storage
password = "user_password"
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
Session Management
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Strict'
SESSION_TIMEOUT = 30 * 60
3. Sensitive Data Exposure
Encryption in Transit
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
Encryption at Rest
from cryptography.fernet import Fernet
cipher = Fernet(encryption_key)
encrypted_data = cipher.encrypt(sensitive_data.encode())
logger.info(f"User logged in")
4. XML External Entities (XXE)
import xml.etree.ElementTree as ET
tree = ET.parse(user_file)
from defusedxml import ElementTree as ET
tree = ET.parse(user_file)
5. Broken Access Control
@app.route('/users/<user_id>')
def get_user(user_id):
return User.get(user_id)
@app.route('/users/<user_id>')
@login_required
def get_user(user_id):
if current_user.id != user_id and not current_user.is_admin:
abort(403)
return User.get(user_id)
6. Security Misconfiguration
Checklist:
DEBUG = True
SHOW_ERRORS = True
DEBUG = False
SHOW_ERRORS = False
ALLOWED_HOSTS = ['yourdomain.com']
7. Cross-Site Scripting (XSS)
Stored XSS
return f"<div>Welcome, {username}</div>"
from html import escape
return f"<div>Welcome, {escape(username)}</div>"
DOM-based XSS
element.innerHTML = userInput;
element.textContent = userInput;
Content Security Policy (CSP)
response.headers['Content-Security-Policy'] = (
"default-src 'self'; "
"script-src 'self' 'unsafe-inline'; "
"style-src 'self' 'unsafe-inline'"
)
8. Insecure Deserialization
import pickle
data = pickle.loads(untrusted_data)
import json
data = json.loads(untrusted_data)
9. Using Components with Known Vulnerabilities
Best Practices:
pip list --outdated
npm audit
pip-audit
npm audit fix
pip freeze > requirements.txt
npm ci
10. Insufficient Logging & Monitoring
import logging
logger.warning(f"Failed login attempt for user: {email} from IP: {ip_address}")
logger.critical(f"Potential SQL injection detected: {suspicious_input}")
Input Validation
Allowlist Approach
if '<script>' not in user_input:
process(user_input)
import re
if re.match(r'^[a-zA-Z0-9_-]+$', user_input):
process(user_input)
else:
raise ValueError("Invalid input")
Type Validation
from pydantic import BaseModel, EmailStr, constr
class UserInput(BaseModel):
email: EmailStr
age: int = Field(ge=0, le=150)
username: constr(min_length=3, max_length=20, regex=r'^[a-zA-Z0-9_]+$')
Cross-Site Request Forgery (CSRF)
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
@app.route('/api/data', methods=['POST'])
@csrf.exempt
def api_data():
if request.headers.get('X-CSRF-Token') != session['csrf_token']:
abort(403)
API Security
Rate Limiting
from flask_limiter import Limiter
limiter = Limiter(app, key_func=lambda: request.remote_addr)
@app.route('/api/login', methods=['POST'])
@limiter.limit("5 per minute")
def login():
pass
API Authentication
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
import jwt
from datetime import datetime, timedelta
token = jwt.encode({
'user_id': user.id,
'exp': datetime.utcnow() + timedelta(hours=1)
}, secret_key, algorithm='HS256')
File Upload Security
import os
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'pdf'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['POST'])
def upload_file():
file = request.files['file']
if not allowed_file(file.filename):
abort(400)
filename = secure_filename(file.filename)
if len(file.read()) > 5 * 1024 * 1024:
abort(413)
file.save(os.path.join('/var/uploads', filename))
Security Headers
@app.after_request
def set_security_headers(response):
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-XSS-Protection'] = '1; mode=block'
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
response.headers['Content-Security-Policy'] = "default-src 'self'"
return response
Secrets Management
API_KEY = "sk_live_123456789"
import os
API_KEY = os.environ.get('API_KEY')
Security Review Checklist
Code Review
Pre-Production
Usage Instructions
When this skill is active:
- Review code for OWASP Top 10 vulnerabilities
- Suggest secure alternatives to vulnerable code
- Identify missing security controls
- Recommend security best practices
- Validate input/output handling
- Check for hardcoded secrets and sensitive data exposure