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