| name | security-checklist |
| description | Use this skill when implementing security measures or conducting security audits. Provides OWASP Top 10 mitigations, authentication patterns, input validation strategies, and compliance guidelines. Ensures applications are secure against common vulnerabilities. |
| version | 1.0.0 |
| author | AI Agent Hub |
| tags | security, owasp, authentication, compliance, vulnerabilities |
Security Checklist
Overview
This skill provides comprehensive security guidance for building secure applications. Whether performing a security audit, implementing new features, or hardening existing systems, this framework helps identify and mitigate common vulnerabilities.
When to use this skill:
- Conducting security audits or reviews
- Implementing authentication and authorization
- Validating and sanitizing user input
- Handling sensitive data (PII, credentials, payment info)
- Ensuring compliance (GDPR, HIPAA, SOC2)
- Preparing for security assessments or penetration tests
- Reviewing third-party dependencies for vulnerabilities
Required Tools
This skill requires the following tools to be installed on your system:
For JavaScript/TypeScript Projects
- Node.js 18+ with npm
- Command:
npm audit - Install: Node.js comes with npm pre-installed
For Python Projects
- Python 3.8+ with pip
- pip-audit: Security scanner for Python dependencies
- Install:
pip install pip-audit - Command:
pip-audit
- Install:
Optional (Advanced Security Scanning)
Semgrep: Static analysis tool
- Install (macOS):
brew install semgrep - Install (pip):
pip install semgrep - Command:
semgrep --config=auto .
- Install (macOS):
Bandit: Python security linter
- Install:
pip install bandit - Command:
bandit -r .
- Install:
TruffleHog: Secrets detection
- Install (macOS):
brew install trufflesecurity/trufflehog/trufflehog - Install (Go):
go install github.com/trufflesecurity/trufflehog/v3@latest - Command:
trufflehog filesystem .
- Install (macOS):
Installation Verification
# Verify Node.js & npm
node --version
npm --version
# Verify Python & pip
python --version
pip --version
# Verify pip-audit
pip-audit --version
# Verify optional tools
semgrep --version
bandit --version
trufflehog --version
Note: The skill will automatically detect which tools are available and use appropriate commands for your project type.
Security Principles
Defense in Depth
- Multiple layers of security controls
- Assume each layer can fail, design redundancy
- Security at database, application, network, and infrastructure levels
Least Privilege
- Grant minimum permissions necessary
- Separate read/write database accounts
- Service accounts with limited scope
Fail Securely
- Errors don't expose sensitive information
- Authentication failures don't reveal if user exists
- Rate limiting prevents brute force attacks
Don't Trust User Input
- All input is untrusted until validated
- Validate, sanitize, and escape
- Apply principle to query params, headers, cookies, POST data
OWASP Top 10 (2021 Edition)
1. Broken Access Control
Vulnerability: Users can access resources they shouldn't.
Examples:
# ❌ Bad: No authorization check
@app.route('/api/users/<user_id>')
def get_user(user_id):
return db.query(f"SELECT * FROM users WHERE id = {user_id}")
# ✅ Good: Verify user can access this resource
@app.route('/api/users/<user_id>')
@login_required
def get_user(user_id):
current_user = get_current_user()
if current_user.id != user_id and not current_user.is_admin:
abort(403, "Forbidden")
return db.query("SELECT * FROM users WHERE id = ?", [user_id])
Mitigations:
- Deny by default (require explicit authorization)
- Enforce ownership checks (users can only access their own data)
- Implement RBAC (Role-Based Access Control)
- Test for IDOR (Insecure Direct Object References)
- Log access control failures
2. Cryptographic Failures
Vulnerability: Sensitive data exposed due to weak or missing encryption.
Examples:
# ❌ Bad: Storing passwords in plaintext
user.password = request.form['password']
# ✅ Good: Hashing passwords with bcrypt
from bcrypt import hashpw, gensalt
hashed = hashpw(password.encode('utf-8'), gensalt())
user.password_hash = hashed
# ❌ Bad: Using weak hashing (MD5, SHA1)
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()
# ✅ Good: Using strong hashing (bcrypt, argon2, scrypt)
from argon2 import PasswordHasher
ph = PasswordHasher()
password_hash = ph.hash(password)
Mitigations:
- Use TLS/HTTPS for all traffic (enforce, not optional)
- Hash passwords with bcrypt, argon2, or scrypt
- Encrypt sensitive data at rest (PII, payment info)
- Never store credit card numbers (use tokenization)
- Use strong random number generators (
secretsmodule in Python) - Rotate encryption keys regularly
3. Injection (SQL, NoSQL, Command, LDAP)
Vulnerability: Untrusted data sent to an interpreter as part of a command.
SQL Injection:
# ❌ Bad: String concatenation (vulnerable to SQL injection)
query = f"SELECT * FROM users WHERE email = '{email}'"
db.execute(query)
# ✅ Good: Parameterized queries
query = "SELECT * FROM users WHERE email = ?"
db.execute(query, [email])
Command Injection:
# ❌ Bad: Shell=True with user input
import subprocess
filename = request.form['filename']
subprocess.run(f"cat {filename}", shell=True)
# ✅ Good: Avoid shell, use list arguments
subprocess.run(["cat", filename], shell=False)
Mitigations:
- Use parameterized queries (prepared statements)
- Use ORMs with proper query builders
- Validate and sanitize all input
- Avoid
eval(),exec(), shell=True - Use allowlists for permitted values
- Escape special characters in dynamic queries
4. Insecure Design
Vulnerability: Design flaws that can't be fixed with implementation.
Examples:
- No rate limiting on login/password reset
- Unlimited file upload sizes
- Sequential or guessable IDs
- Password reset without account verification
Mitigations:
- Threat modeling during design phase
- Rate limiting on all public endpoints
- Use UUIDs instead of sequential IDs for public resources
- Require email verification for password resets
- Implement CAPTCHA for sensitive operations
- Design for secure defaults (opt-in, not opt-out)
5. Security Misconfiguration
Vulnerability: Default configs, incomplete setups, verbose errors.
Examples:
# ❌ Bad: Debug mode in production
app.debug = True
# ✅ Good: Debug mode only in development
app.debug = os.getenv('FLASK_ENV') == 'development'
# ❌ Bad: Verbose error messages
@app.errorhandler(Exception)
def handle_error(e):
return str(e), 500 # Exposes stack traces
# ✅ Good: Generic error messages
@app.errorhandler(Exception)
def handle_error(e):
logger.error(f"Error: {e}")
return {"error": "Internal server error"}, 500
Mitigations:
- Disable debug mode in production
- Remove default credentials
- Close unnecessary ports and services
- Set security headers (CSP, X-Frame-Options, HSTS)
- Keep software updated (dependencies, frameworks, OS)
- Use environment variables for secrets (not hardcoded)
6. Vulnerable and Outdated Components
Vulnerability: Using libraries with known vulnerabilities.
Mitigations:
# Check for vulnerabilities
npm audit
npm audit fix
# Python
pip-audit
safety check
Best Practices:
- Pin dependency versions in lock files
- Scan dependencies regularly (CI/CD integration)
- Subscribe to security advisories (GitHub Dependabot, Snyk)
- Update dependencies regularly (monthly at minimum)
- Remove unused dependencies
7. Identification and Authentication Failures
Vulnerability: Weak authentication, credential stuffing, session hijacking.
Examples:
# ❌ Bad: Weak password requirements
if len(password) < 6:
return "Password too short"
# ✅ Good: Strong password requirements
import re
def validate_password(password):
if len(password) < 12:
return "Password must be at least 12 characters"
if not re.search(r"[A-Z]", password):
return "Password must contain uppercase letter"
if not re.search(r"[a-z]", password):
return "Password must contain lowercase letter"
if not re.search(r"[0-9]", password):
return "Password must contain a number"
return None # Valid
Mitigations:
- Require strong passwords (12+ chars, mixed case, numbers, symbols)
- Implement multi-factor authentication (MFA)
- Rate limit login attempts (5 attempts per 15 minutes)
- Use secure session management (HTTPOnly, Secure, SameSite cookies)
- Invalidate sessions after logout or inactivity
- Don't reveal whether email exists during password reset
- Implement account lockout after failed attempts
8. Software and Data Integrity Failures
Vulnerability: Code or infrastructure updates without integrity verification.
Examples:
- Loading libraries from untrusted CDNs
- No verification of CI/CD pipeline artifacts
- Auto-update without signature verification
Mitigations:
- Use Subresource Integrity (SRI) for CDN scripts
<script src="https://cdn.example.com/lib.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
- Verify package signatures (npm, PyPI)
- Review code changes before deployment
- Use signed commits and releases
9. Security Logging and Monitoring Failures
Vulnerability: Insufficient logging prevents detection of breaches.
Examples:
# ❌ Bad: No logging
@app.route('/login', methods=['POST'])
def login():
user = authenticate(email, password)
return {"token": create_token(user)}
# ✅ Good: Log security events
import logging
@app.route('/login', methods=['POST'])
def login():
email = request.form['email']
user = authenticate(email, password)
if user:
logger.info(f"Successful login: {email}")
return {"token": create_token(user)}
else:
logger.warning(f"Failed login attempt: {email}")
return {"error": "Invalid credentials"}, 401
Mitigations:
- Log all authentication events (login, logout, failed attempts)
- Log authorization failures (403 errors)
- Log input validation failures
- Log security-relevant events (password changes, MFA changes)
- Centralize logs (ELK, Splunk, CloudWatch)
- Set up alerts for suspicious patterns
- Never log passwords, tokens, or sensitive data
10. Server-Side Request Forgery (SSRF)
Vulnerability: Application fetches remote resources without validating URL.
Examples:
# ❌ Bad: Fetching user-provided URL without validation
import requests
@app.route('/fetch')
def fetch():
url = request.args.get('url')
response = requests.get(url) # Can access internal services!
return response.text
# ✅ Good: Validate URL and use allowlist
from urllib.parse import urlparse
ALLOWED_DOMAINS = ['api.example.com', 'cdn.example.com']
@app.route('/fetch')
def fetch():
url = request.args.get('url')
parsed = urlparse(url)
if parsed.hostname not in ALLOWED_DOMAINS:
abort(400, "Invalid domain")
response = requests.get(url, timeout=5)
return response.text
Mitigations:
- Validate and sanitize all URLs
- Use allowlist of permitted domains
- Disable redirects or validate redirect targets
- Block access to internal IPs (127.0.0.1, 10.0.0.0/8, 192.168.0.0/16)
- Network segmentation (separate internal and external services)
Authentication & Authorization
Password Security
# ✅ Secure password hashing
from argon2 import PasswordHasher
ph = PasswordHasher()
# Hashing
password_hash = ph.hash(password)
# Verification
try:
ph.verify(password_hash, password)
# Password correct
except:
# Password incorrect
pass
Requirements:
- Minimum 12 characters
- Mix of upper/lowercase, numbers, symbols
- No common passwords (use haveibeenpwned)
- Bcrypt, Argon2, or scrypt for hashing
- Salt automatically handled by these algorithms
Session Management
# ✅ Secure session cookies
app.config['SESSION_COOKIE_SECURE'] = True # HTTPS only
app.config['SESSION_COOKIE_HTTPONLY'] = True # No JavaScript access
app.config['SESSION_COOKIE_SAMESITE'] = 'Strict' # CSRF protection
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1)
JWT Tokens
import jwt
from datetime import datetime, timedelta
# ✅ Secure JWT generation
def create_token(user_id):
payload = {
'user_id': user_id,
'exp': datetime.utcnow() + timedelta(hours=1), # Expiration
'iat': datetime.utcnow(), # Issued at
}
return jwt.encode(payload, SECRET_KEY, algorithm='HS256')
# ✅ Secure JWT verification
def verify_token(token):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
return payload['user_id']
except jwt.ExpiredSignatureError:
return None # Token expired
except jwt.InvalidTokenError:
return None # Invalid token
Input Validation & Sanitization
Validation
# ✅ Allowlist validation
def validate_sort_column(column):
allowed_columns = ['name', 'email', 'created_at']
if column not in allowed_columns:
raise ValueError("Invalid sort column")
return column
# ✅ Type validation
from pydantic import BaseModel, EmailStr, constr
class UserCreate(BaseModel):
email: EmailStr
name: constr(min_length=2, max_length=100)
age: int = Field(ge=0, le=150)
# Usage
try:
user = UserCreate(**request.json)
except ValidationError as e:
return {"errors": e.errors()}, 400
Sanitization
# ✅ HTML escaping
from markupsafe import escape
@app.route('/comment', methods=['POST'])
def create_comment():
content = escape(request.form['content'])
db.execute("INSERT INTO comments (content) VALUES (?)", [content])
return {"status": "ok"}
Security Headers
# ✅ Set security headers
@app.after_request
def set_security_headers(response):
response.headers['Content-Security-Policy'] = "default-src 'self'"
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'
return response
🔍 Automated Security Scanning (v3.5.0)
Overview
Automated security scanning catches vulnerabilities early. This section teaches agents HOW to run security tools and record evidence.
When to auto-scan:
- Before marking code review as complete
- After installing/updating dependencies
- During CI/CD pipeline execution
- When adding new external integrations
- Before production deployments
Scanning Workflow
1. Identify Scan Type (dependencies, code, configuration)
2. Run Appropriate Tool (npm audit, pip-audit, semgrep)
3. Capture Results (exit codes, vulnerability counts)
4. Record Evidence in Context
5. Escalate Critical Findings
1. Dependency Vulnerability Scanning
JavaScript/TypeScript (NPM)
# Run npm audit and capture results
npm audit --json > security-audit.json
EXIT_CODE=$?
# Check exit code
if [ $EXIT_CODE -eq 0 ]; then
echo "✅ No vulnerabilities found"
else
echo "⚠️ Vulnerabilities detected (exit code: $EXIT_CODE)"
fi
# Parse for critical/high vulnerabilities
CRITICAL=$(npm audit --json | jq '.metadata.vulnerabilities.critical')
HIGH=$(npm audit --json | jq '.metadata.vulnerabilities.high')
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "🚨 CRITICAL: $CRITICAL critical, $HIGH high severity vulnerabilities"
fi
Record evidence:
context.quality_evidence = context.quality_evidence || { last_updated: new Date().toISOString() };
context.quality_evidence.security_scan = {
executed: true,
tool: 'npm audit',
critical: 2,
high: 5,
moderate: 10,
low: 3,
timestamp: new Date().toISOString()
};
context.writeContext();
Python (pip-audit / safety)
# Using pip-audit (official tool)
pip-audit --format=json > security-audit.json
EXIT_CODE=$?
# Alternative: using safety
safety check --json > security-audit.json
# Check for critical vulnerabilities
CRITICAL_COUNT=$(cat security-audit.json | jq '[.vulnerabilities[] | select(.severity == "critical")] | length')
Evidence recording:
# Record in context
context['quality_evidence'] = context.get('quality_evidence', {})
context['quality_evidence']['security_scan'] = {
'executed': True,
'tool': 'pip-audit',
'critical': critical_count,
'high': high_count,
'moderate': moderate_count,
'low': low_count,
'timestamp': datetime.now().isoformat()
}
2. Static Code Analysis (SAST)
Semgrep (Multi-language)
# Run Semgrep with security rules
semgrep --config=auto --json > semgrep-results.json
EXIT_CODE=$?
# Count findings by severity
CRITICAL=$(cat semgrep-results.json | jq '[.results[] | select(.extra.severity == "ERROR")] | length')
HIGH=$(cat semgrep-results.json | jq '[.results[] | select(.extra.severity == "WARNING")] | length')
Common security patterns detected:
- SQL Injection
- XSS (Cross-Site Scripting)
- Command Injection
- Path Traversal
- Hardcoded secrets
- Insecure cryptography
Bandit (Python)
# Run Bandit for Python security issues
bandit -r . -f json -o bandit-report.json
EXIT_CODE=$?
# Count high/medium severity issues
HIGH=$(cat bandit-report.json | jq '[.results[] | select(.issue_severity == "HIGH")] | length')
MEDIUM=$(cat bandit-report.json | jq '[.results[] | select(.issue_severity == "MEDIUM")] | length')
3. Secret Detection
TruffleHog / Gitleaks
# Scan for secrets in git history
trufflehog git file://. --json > secrets-scan.json
# Check if any secrets found
SECRET_COUNT=$(cat secrets-scan.json | jq '. | length')
if [ "$SECRET_COUNT" -gt 0 ]; then
echo "🚨 CRITICAL: $SECRET_COUNT secrets detected!"
# Extract types
cat secrets-scan.json | jq -r '.[] | .DetectorType' | sort | uniq
fi
Common secrets detected:
- AWS API keys
- GitHub tokens
- Private keys (RSA, SSH)
- Database credentials
- API keys (Stripe, Twilio, etc.)
4. Container Security (Docker)
# Scan Docker images with Trivy
trivy image myapp:latest --format json > trivy-scan.json
# Count vulnerabilities
CRITICAL=$(cat trivy-scan.json | jq '[.Results[].Vulnerabilities[]? | select(.Severity == "CRITICAL")] | length')
HIGH=$(cat trivy-scan.json | jq '[.Results[].Vulnerabilities[]? | select(.Severity == "HIGH")] | length')
5. Evidence Recording Template
After running security scans, record evidence in shared context:
import { ContextManager } from '../lib/context/context-manager.js';
const context = new ContextManager();
// Record security scan evidence
context.recordSecurityScanEvidence({
executed: true,
tool: 'npm audit + semgrep',
critical: 2,
high: 5,
moderate: 10,
low: 3,
timestamp: new Date().toISOString(),
scan_details: {
dependency_scan: {
tool: 'npm audit',
critical: 2,
high: 3,
vulnerabilities: [
{ id: 'GHSA-xxxx', severity: 'critical', package: 'lodash@4.17.19' }
]
},
code_scan: {
tool: 'semgrep',
critical: 0,
high: 2,
patterns: ['sql-injection', 'xss']
}
}
});
6. Critical Threshold Escalation
MANDATORY: Escalate if critical/high vulnerabilities found
// After scanning
const securityEvidence = context.getQualityEvidence()?.security_scan;
if (!securityEvidence) {
console.log('⚠️ WARNING: No security scan performed');
return;
}
// Check for critical/high vulnerabilities
if (securityEvidence.critical > 0 || securityEvidence.high > 5) {
console.log('🚨 SECURITY ALERT: Critical vulnerabilities detected');
// BLOCK deployment
const blockingReasons = [];
if (securityEvidence.critical > 0) {
blockingReasons.push(`${securityEvidence.critical} CRITICAL vulnerabilities`);
}
if (securityEvidence.high > 5) {
blockingReasons.push(`${securityEvidence.high} HIGH vulnerabilities (>5 threshold)`);
}
// Escalate to user
console.log('BLOCKED: ' + blockingReasons.join(', '));
console.log('Action Required: Fix critical/high vulnerabilities before proceeding');
return { approved: false, blockingReasons };
}
console.log('✅ Security scan passed');
Escalation Thresholds:
- CRITICAL: Any critical vulnerability → BLOCK
- HIGH: >5 high severity vulnerabilities → BLOCK
- MODERATE: >20 moderate vulnerabilities → WARNING
- LOW: >50 low vulnerabilities → WARNING
7. Auto-Scan Checklist
Use this checklist when performing security reviews:
## Security Scan Checklist
- [ ] **Dependency Scan**: npm audit / pip-audit executed
- [ ] **Exit Code Captured**: 0 = clean, non-zero = vulnerabilities
- [ ] **Severity Counts**: Critical, High, Moderate, Low recorded
- [ ] **Evidence Recorded**: Added to context.quality_evidence.security_scan
- [ ] **Critical Threshold Check**: BLOCK if critical > 0 or high > 5
- [ ] **Scan Results Saved**: JSON output saved for review
- [ ] **False Positives Noted**: Known safe issues documented
- [ ] **Fix Recommendations**: Upgrade paths or mitigations documented
8. Integration with Code Quality Reviewer
When Code Quality Reviewer agent performs review:
1. Run linter/type checker (already implemented)
2. **AUTO-TRIGGER**: Run security scan
- npm audit (for JS/TS projects)
- pip-audit (for Python projects)
3. Capture and record evidence
4. Check critical thresholds
5. BLOCK approval if critical vulnerabilities found
6. Include security scan summary in review output
Example output:
## Code Quality Review
### Lint & Type Check: ✅ PASS
- ESLint: 0 errors, 2 warnings
- TypeScript: 0 errors
### Security Scan: ⚠️ WARNING
- Tool: npm audit
- Critical: 0
- High: 3
- Moderate: 8
- Low: 2
**Recommendation**: 3 high severity vulnerabilities detected. Run `npm audit fix` to address:
- lodash@4.17.19 (Prototype Pollution - High)
- minimist@1.2.5 (Prototype Pollution - High)
- axios@0.21.1 (SSRF - High)
### Overall Status: BLOCKED
Security vulnerabilities must be resolved before approval.
9. Tool Installation Guide
JavaScript/TypeScript:
# npm audit (built-in, no install needed)
npm audit
# Semgrep
pip install semgrep
# TruffleHog
docker run --rm trufflesecurity/trufflehog:latest
Python:
# pip-audit (official tool)
pip install pip-audit
# safety
pip install safety
# Bandit
pip install bandit
General:
# Trivy (containers, dependencies, code)
brew install aquasecurity/trivy/trivy
# Gitleaks (secrets)
brew install gitleaks
Compliance
GDPR (General Data Protection Regulation)
- Data Inventory: Know what personal data you collect
- Lawful Basis: Have legal basis for processing (consent, contract, etc.)
- Privacy Policy: Clear, accessible privacy policy
- User Rights: Implement data access, deletion, portability
- Data Minimization: Collect only necessary data
- Breach Notification: Process for reporting breaches within 72 hours
SOC 2 (Service Organization Control)
- Access Controls: Role-based access, MFA, least privilege
- Encryption: Data encrypted at rest and in transit
- Logging & Monitoring: Audit logs for all security events
- Incident Response: Documented incident response plan
- Vendor Management: Third-party security assessments
Integration with Agents
Code Quality Reviewer
- Applies security checklist during code reviews
- Identifies SQL injection, XSS, and other vulnerabilities
- Validates authentication and authorization patterns
Backend System Architect
- Designs systems with security in mind (defense in depth)
- Plans for least privilege access
- Implements rate limiting and DDOS protection
Frontend UI Developer
- Implements CSP headers
- Prevents XSS through output encoding
- Validates input on client-side (with server-side validation)
Quick Start Checklist
When securing an application:
- All input validated and sanitized
- SQL injection prevented (parameterized queries)
- XSS prevented (output encoding)
- CSRF protection enabled
- HTTPS enforced (no HTTP in production)
- Security headers set (CSP, X-Frame-Options, HSTS)
- Passwords hashed with bcrypt/argon2
- Rate limiting on sensitive endpoints
- Authentication required for protected routes
- Authorization checks on all data access
- Secrets in environment variables (not code)
- Dependencies scanned for vulnerabilities
- Error messages don't leak information
- Logging enabled for security events
- MFA available for users
Skill Version: 1.0.0 Last Updated: 2025-10-31 Maintained by: AI Agent Hub Team