From aeo-security
OWASP Top 10 vulnerabilities with detection patterns, code examples, and prevention checklists. Activate when: reviewing code for security, checking for OWASP vulnerabilities, performing security audits, fixing injection flaws, preventing XSS, securing authentication, checking access control.
npx claudepluginhub aeyeops/aeo-skill-marketplace --plugin aeo-securityThis skill uses the workspace's default tool permissions.
```markdown
Acquire memory dumps from live systems/VMs and analyze with Volatility 3 for processes, networks, DLLs, injections in incident response or malware hunts.
Provides x86-64/ARM disassembly patterns, calling conventions, control flow recognition for static analysis of executables and compiled binaries.
Identifies anti-debugging checks like IsDebuggerPresent, NtQueryInformationProcess in Windows binaries; suggests bypasses via patches/hooks/scripts for malware analysis, CTFs, authorized RE.
Description: Users can act outside their intended permissions — accessing other users'
data, modifying records they shouldn't, or escalating privileges.
Detection patterns:
- URL parameter tampering: /api/users/123 → /api/users/456
- Missing authorization checks on API endpoints
- Direct object references without ownership verification
- Metadata manipulation (JWT role claim, hidden form fields)
- CORS misconfiguration allowing unauthorized origins
# VULNERABLE: No authorization check — any user can view any profile
@app.get("/api/users/{user_id}")
def get_user(user_id: int):
return db.query(User).get(user_id)
# FIXED: Verify the requesting user owns the resource
@app.get("/api/users/{user_id}")
def get_user(user_id: int, current_user: User = Depends(get_current_user)):
if current_user.id != user_id and not current_user.is_admin:
raise HTTPException(status_code=403, detail="Forbidden")
return db.query(User).get(user_id)
Prevention checklist:
- [ ] Deny by default — require explicit grants, not explicit denials
- [ ] Enforce ownership checks on every data access
- [ ] Use server-side session for authorization (don't trust client)
- [ ] Disable directory listing on web servers
- [ ] Rate-limit API access to detect enumeration attempts
- [ ] Log access control failures and alert on patterns
Description: Sensitive data exposed due to weak or missing encryption, including
data in transit, at rest, or during processing.
Detection patterns:
- HTTP instead of HTTPS for sensitive data
- Passwords stored in plaintext or weak hash (MD5, SHA1)
- Hard-coded encryption keys or secrets in source code
- Weak or deprecated TLS versions (TLS 1.0, 1.1)
- Sensitive data in URL parameters (logged by proxies)
# VULNERABLE: Weak password hashing
import hashlib
hashed = hashlib.md5(password.encode()).hexdigest()
# FIXED: Use bcrypt with appropriate cost factor
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
Prevention checklist:
- [ ] Classify data by sensitivity; apply controls accordingly
- [ ] Use TLS 1.2+ for all data in transit; enforce HSTS
- [ ] Hash passwords with bcrypt, scrypt, or Argon2 (never MD5/SHA1)
- [ ] Use authenticated encryption (AES-GCM, ChaCha20-Poly1305)
- [ ] Manage keys in a secrets vault (not in source code)
- [ ] Disable caching for responses containing sensitive data
Description: User-supplied data is sent to an interpreter as part of a command
or query — allowing attackers to execute arbitrary commands.
Detection patterns:
- String concatenation in SQL queries
- User input passed directly to shell commands
- Template strings with user input (SSTI)
- LDAP, XPath, or NoSQL queries built from user input
- Dynamic code execution (eval, exec) with user input
# VULNERABLE: SQL injection via string formatting
query = f"SELECT * FROM users WHERE email = '{email}'"
cursor.execute(query)
# FIXED: Parameterized query
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
# FIXED: ORM usage (SQLAlchemy)
user = session.query(User).filter(User.email == email).first()
# VULNERABLE: Command injection
import os
os.system(f"convert {user_filename} output.png")
# FIXED: Use subprocess with argument list (no shell)
import subprocess
subprocess.run(["convert", user_filename, "output.png"], check=True)
Prevention checklist:
- [ ] Use parameterized queries or ORM for all database access
- [ ] Use subprocess with argument lists instead of os.system/shell=True
- [ ] Validate and sanitize all user input on the server side
- [ ] Apply least-privilege database permissions
- [ ] Never use eval() or exec() with user-controlled input
- [ ] Use allowlists for expected input values where possible
Description: Fundamental design flaws that cannot be fixed by implementation
alone — missing threat modeling, insecure business logic, or absent controls.
Detection patterns:
- No rate limiting on authentication or sensitive operations
- Password reset via security questions (easily guessed)
- Business logic that trusts client-side calculations
- No account lockout after failed login attempts
- Missing audit trail for sensitive operations
Prevention checklist:
- [ ] Threat model during design phase
- [ ] Define security requirements alongside functional requirements
- [ ] Use secure design patterns (least privilege, defense in depth)
- [ ] Validate business logic on the server, never the client
- [ ] Implement rate limiting on sensitive endpoints
- [ ] Design with abuse cases in mind, not just use cases
Description: Insecure defaults, incomplete configurations, verbose error messages,
or unnecessary features enabled in production.
Detection patterns:
- Default credentials still active (admin/admin)
- Debug mode enabled in production
- Verbose error messages exposing stack traces to users
- Unnecessary HTTP methods enabled (TRACE, DELETE)
- Missing security headers (CSP, X-Frame-Options, etc.)
- Cloud storage buckets publicly accessible
# VULNERABLE: Debug mode in production
app = Flask(__name__)
app.run(debug=True) # Exposes interactive debugger to attackers
# FIXED: Environment-based configuration
app = Flask(__name__)
app.config["DEBUG"] = os.environ.get("FLASK_DEBUG", "false").lower() == "true"
Prevention checklist:
- [ ] Remove default credentials before deployment
- [ ] Disable debug mode, verbose errors, and stack traces in production
- [ ] Set security headers: CSP, HSTS, X-Content-Type-Options, X-Frame-Options
- [ ] Remove unnecessary features, endpoints, and sample code
- [ ] Automate configuration hardening with infrastructure-as-code
- [ ] Regularly scan for misconfigurations (cloud posture management)
Description: Using components (libraries, frameworks, OS) with known vulnerabilities
or that are no longer maintained.
Detection patterns:
- Dependencies with known CVEs (check advisories)
- Libraries that haven't been updated in years
- Components past end-of-life (Python 2, Node 12, etc.)
- No automated dependency scanning in CI pipeline
Prevention checklist:
- [ ] Maintain an inventory of all components and versions
- [ ] Remove unused dependencies
- [ ] Monitor for CVEs: pip-audit, npm audit, Dependabot, Snyk
- [ ] Subscribe to security advisories for critical dependencies
- [ ] Update dependencies regularly (automated PRs via Dependabot/Renovate)
- [ ] Use lock files to ensure reproducible builds
Description: Weaknesses in authentication that allow attackers to compromise
passwords, keys, or session tokens.
Detection patterns:
- Weak password policy (no minimum length, no complexity)
- Credential stuffing possible (no rate limiting on login)
- Session tokens in URL parameters
- Session not invalidated on logout or password change
- Missing multi-factor authentication for sensitive operations
# VULNERABLE: Predictable session tokens
import random
session_id = str(random.randint(1, 999999))
# FIXED: Cryptographically random session tokens
import secrets
session_id = secrets.token_urlsafe(32)
Prevention checklist:
- [ ] Enforce strong passwords (minimum 8 chars, check against breach lists)
- [ ] Implement MFA for login and sensitive operations
- [ ] Rate-limit and temporarily lock after repeated failed logins
- [ ] Use cryptographically random session tokens
- [ ] Invalidate sessions on logout, password change, and timeout
- [ ] Never expose session tokens in URLs or logs
Description: Code and infrastructure that doesn't verify integrity — insecure
CI/CD pipelines, auto-updates without verification, or deserialization of untrusted data.
Detection patterns:
- Deserializing untrusted data (pickle, Java serialization, YAML load)
- CI/CD pipeline without integrity checks on artifacts
- Dependencies pulled without checksum verification
- Auto-update mechanism without signature verification
# VULNERABLE: Deserializing untrusted data
import pickle
data = pickle.loads(user_input) # Arbitrary code execution!
# FIXED: Use safe serialization formats
import json
data = json.loads(user_input) # Only parses data, no code execution
Prevention checklist:
- [ ] Never deserialize untrusted data with pickle, eval, or yaml.load
- [ ] Use json, yaml.safe_load, or schema-validated parsers
- [ ] Verify integrity of dependencies (checksums, lock files)
- [ ] Sign and verify CI/CD artifacts
- [ ] Implement code review for CI/CD pipeline changes
Description: Insufficient logging, missing monitoring, or lack of incident response
capability — attacks go undetected.
Detection patterns:
- No logging of authentication events (login, logout, failures)
- Logs don't include enough context (who, what, when, where)
- No alerting on suspicious patterns (brute force, enumeration)
- Logs stored only locally (lost if server compromised)
- No incident response plan
Prevention checklist:
- [ ] Log all authentication events (success and failure)
- [ ] Log all access control failures
- [ ] Log all input validation failures (potential attack probes)
- [ ] Include context: timestamp, user ID, IP, action, result
- [ ] Ship logs to centralized, tamper-resistant storage
- [ ] Set up alerts for suspicious patterns
- [ ] Never log sensitive data (passwords, tokens, PII)
- [ ] Test that logging works (include in incident response drills)
Description: Application fetches a remote resource using a user-supplied URL
without validation — allowing attackers to reach internal services.
Detection patterns:
- User can provide a URL that the server fetches
- No allowlist for permitted domains or IP ranges
- Internal metadata endpoints accessible (169.254.169.254)
- URL redirects not followed safely
# VULNERABLE: Fetch any URL the user provides
import requests
response = requests.get(user_provided_url)
# FIXED: Validate URL against allowlist
from urllib.parse import urlparse
ALLOWED_HOSTS = {"api.example.com", "cdn.example.com"}
def safe_fetch(url: str):
parsed = urlparse(url)
if parsed.hostname not in ALLOWED_HOSTS:
raise ValueError(f"Host not allowed: {parsed.hostname}")
if parsed.scheme not in ("http", "https"):
raise ValueError(f"Scheme not allowed: {parsed.scheme}")
return requests.get(url, allow_redirects=False, timeout=10)
Prevention checklist:
- [ ] Validate and sanitize all user-supplied URLs
- [ ] Use allowlists for permitted domains and protocols
- [ ] Block requests to private/internal IP ranges (10.x, 172.16.x, 192.168.x, 169.254.x)
- [ ] Disable HTTP redirects or re-validate after redirect
- [ ] Use network-level segmentation (services can't reach metadata endpoints)
- [ ] Monitor outbound requests for anomalies