skills/ariegoldkin/security-checklist/SKILL.md
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.
npx skillsauth add aiskillstore/marketplace security-checklistInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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:
This skill requires the following tools to be installed on your system:
npm auditpip install pip-auditpip-auditSemgrep: Static analysis tool
brew install semgreppip install semgrepsemgrep --config=auto .Bandit: Python security linter
pip install banditbandit -r .TruffleHog: Secrets detection
brew install trufflesecurity/trufflehog/trufflehoggo install github.com/trufflesecurity/trufflehog/v3@latesttrufflehog filesystem .# 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.
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:
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:
secrets module in Python)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:
eval(), exec(), shell=TrueVulnerability: Design flaws that can't be fixed with implementation.
Examples:
Mitigations:
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:
Vulnerability: Using libraries with known vulnerabilities.
Mitigations:
# Check for vulnerabilities
npm audit
npm audit fix
# Python
pip-audit
safety check
Best Practices:
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:
Vulnerability: Code or infrastructure updates without integrity verification.
Examples:
Mitigations:
<script src="https://cdn.example.com/lib.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
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:
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:
# ✅ 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:
# ✅ 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)
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
# ✅ 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
# ✅ 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"}
# ✅ 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 catches vulnerabilities early. This section teaches agents HOW to run security tools and record evidence.
When to auto-scan:
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
# 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();
# 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()
}
# 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:
# 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')
# 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:
# 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')
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: '[email protected]' }
]
},
code_scan: {
tool: 'semgrep',
critical: 0,
high: 2,
patterns: ['sql-injection', 'xss']
}
}
});
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:
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
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:
- [email protected] (Prototype Pollution - High)
- [email protected] (Prototype Pollution - High)
- [email protected] (SSRF - High)
### Overall Status: BLOCKED
Security vulnerabilities must be resolved before approval.
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
When securing an application:
Skill Version: 1.0.0 Last Updated: 2025-10-31 Maintained by: AI Agent Hub Team
development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.