Expert guidance on secure coding practices, focusing on preventing common security errors made by AI during code generation. Use for: auditing AI-generated code, implementing secure design patterns, and ensuring code follows OWASP Top 10 standards. Covers input validation, authentication, cryptography, file handling, secure configuration, and business logic security.
This skill establishes security as a first-class citizen in code generation and review. It recognizes that AI-generated code often prioritizes functionality over security, inheriting and propagating vulnerabilities from training data. This skill provides comprehensive guardrails, checklists, and verification steps to ensure all code—especially AI-generated—is robust, secure, and follows industry best practices.
Critical Understanding: Why AI Code is Often Insecure
AI models optimize for "working code" and "correct-looking output" before "secure and robust code." This introduces classic vulnerabilities at concerning rates:
Root Causes of AI Security Failures
Functionality over Security: If the prompt doesn't explicitly demand security, the model prioritizes the shortest solution even if it uses eval(), SQL string concatenation, or hardcoded keys.
Learning from Insecure Examples: A significant portion of publicly available code contains bad practices (hardcoded secrets, weak encryption, missing validation), and models reproduce these patterns.
Lack of Context Awareness: AI doesn't understand your business rules, threat model, or compliance requirements (PCI-DSS, HIPAA, GDPR), filling gaps with dangerous assumptions.
High CWE Rates in Studies: Empirical research consistently finds serious vulnerabilities (SQLi, XSS, buffer overflows, crypto misuse, hardcoded credentials) in AI-generated code samples.
The Security Non-Negotiables
These rules must NEVER be violated, regardless of convenience or "example purposes":
Never Prioritize Simplicity Over Security: Do not provide "clean" examples that omit input validation or use insecure defaults, even with disclaimers.
Treat AI Output as Untrusted: Always audit AI-generated snippets for hallucinated libraries, outdated patterns, and missing security controls.
Fail Closed: All logic must default to "Access Denied" if an exception occurs, validation fails, or state is unclear.
No Hardcoded Secrets: Never suggest code with hardcoded API keys, passwords, tokens, or cryptographic keys. Always use environment variables, secret managers, or secure vaults.
Parameterized Everything: Never use string concatenation or formatting for SQL queries, OS commands, HTML rendering, or LDAP filters.
Validate All Inputs: Every piece of external data must be validated and sanitized before use.
Defense in Depth: Never rely on a single security control; implement multiple layers of protection.
Comprehensive Security Checklist
1. Input Validation and Injection Prevention
The Problem: AI frequently omits input validation and sanitization unless explicitly requested, leading to CWE-20 (Improper Input Validation) and the entire injection vulnerability family (SQLi, XSS, OS Command Injection, LDAP Injection).
Research Finding: Multiple studies identify SQL injection, XSS, and OS command injection as recurrent vulnerabilities in LLM-generated code.
Checklist
Validate and normalize ALL user input before use, including:
Query parameters (URL parameters)
Request body (JSON, form data)
Headers (including custom headers)
Path parameters
File uploads
WebSocket messages
GraphQL inputs
Use allowlists over denylists: Define what is permitted rather than trying to block what is malicious. Use strict type checking, enum validation, and schema validation.
Parameterized queries ONLY: Never concatenate strings to build SQL queries, shell commands, LDAP filters, XPath expressions, or NoSQL queries. Always use:
Prepared statements with bound parameters
ORM query builders with parameterized methods
Safe API abstractions that prevent injection
XSS Prevention: Escape or sanitize all data before rendering in HTML contexts:
Avoid innerHTML, document.write, and similar dangerous APIs
Implement Content Security Policy (CSP) headers
Disable dangerous evaluation: Never use eval(), Function(), exec(), child_process.exec(), Runtime.exec(), os.system(), or similar on user-controlled data. If dynamic execution is absolutely necessary, use strict sandboxing and allowlists.
Strict regex validation: When using regular expressions for validation:
Prefer exact match patterns (^pattern$) over partial matches
Avoid overly permissive patterns
Be aware of ReDoS (Regular Expression Denial of Service) vulnerabilities
Verification Steps
Before considering input handling complete:
Fuzz Test: Test with unexpected inputs (null, empty strings, very long strings, special characters, Unicode, binary data)
Injection Test: Attempt SQL, NoSQL, command, and XSS injection payloads
Boundary Test: Test at and beyond length limits, type boundaries, and range limits
Negative Test: Ensure invalid inputs are rejected with appropriate errors
Common AI Mistakes to Avoid
# ❌ NEVER DO THIS - SQL Injection vulnerability
query = f"SELECT * FROM users WHERE id = {user_id}"
cursor.execute(query)
# ✅ DO THIS INSTEAD - Parameterized query
query = "SELECT * FROM users WHERE id = ?"
cursor.execute(query, (user_id,))
# ❌ NEVER DO THIS - XSS vulnerability
element.innerHTML = userInput
// ❌ NEVER DO THIS - Command Injection
const output = exec(`ls ${userInput}`);
// ✅ DO THIS INSTEAD - Safe command execution with allowlist
const allowedCommands = ['list', 'status'];
if (allowedCommands.includes(userInput)) {
const output = execFile('ls', [safePath]);
}
2. Authentication, Authorization, and Session Management
The Problem: AI generates authentication flows that "pass happy path tests" but ignore critical security details like rate limiting, constant-time comparison, or fine-grained authorization controls. This enables brute-force attacks, privilege escalation, and API abuse.
Checklist
Secure password storage:
Use modern, memory-hard algorithms: Argon2id (recommended), bcrypt, or scrypt
Never use MD5, SHA1, SHA256 for password hashing (they're too fast)
Always use unique salts per password
Configure appropriate cost factors/work factors
Constant-time comparisons: Compare tokens, passwords, and API keys using constant-time comparison functions to prevent timing attacks:
Python: hmac.compare_digest()
Node.js: crypto.timingSafeEqual()
Java: MessageDigest.isEqual()
Rate limiting and brute-force protection:
Implement rate limiting on login endpoints, password reset, OTP verification, and sensitive APIs
Verify ownership and permissions on every request, not just authentication
Check for IDOR (Insecure Direct Object Reference) vulnerabilities
Validate that users can only access their own resources
Implement attribute-based access control (ABAC) where appropriate
Secure session management:
Use cryptographically secure random session IDs
Implement reasonable session timeouts
Support session revocation and rotation
Regenerate session IDs on privilege changes (login, password change, role change)
Secure cookie configuration:
Set HttpOnly flag (prevents JavaScript access)
Set Secure flag (HTTPS only)
Set SameSite attribute (Strict or Lax)
Use appropriate Max-Age or Expires
Consider __Host- prefix for additional protection
JWT security:
Use strong signing algorithms (RS256, ES256, HS256 with strong secrets)
Never use "none" algorithm or weak secrets
Set short expiration times
Include token rotation and revocation mechanisms
Store tokens securely (not in localStorage for sensitive apps)
Password reset security:
Use cryptographically secure random tokens with high entropy
Implement single-use tokens with short expiration
Do not reveal whether an email exists in the system (privacy protection)
Invalidate existing tokens when new ones are requested
Require re-authentication after password reset
Multi-factor authentication (MFA):
Support TOTP (Time-based One-Time Password)
Support WebAuthn/FIDO2 for strong authentication
Enforce MFA for privileged accounts
Implement backup codes securely
Verification Steps
Brute Force Test: Attempt to guess passwords, session IDs, and tokens
Timing Attack Test: Measure response times for different inputs
Authorization Test: Try to access other users' resources
Session Fixation Test: Verify session ID changes on login
Token Analysis: Check JWT headers and payloads for security issues
Common AI Mistakes to Avoid
# ❌ NEVER DO THIS - Insecure password hashing
hashed = hashlib.md5(password.encode()).hexdigest()
# ✅ DO THIS INSTEAD - Secure password hashing
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# ❌ NEVER DO THIS - Timing attack vulnerability
if token == stored_token:
# authenticate
# ✅ DO THIS INSTEAD - Constant-time comparison
if hmac.compare_digest(token, stored_token):
# authenticate
# ❌ NEVER DO THIS - No rate limiting
@app.route('/login', methods=['POST'])
def login():
# authenticate
# ✅ DO THIS INSTEAD - Rate limiting
@limiter.limit("5 per minute")
@app.route('/login', methods=['POST'])
def login():
# authenticate
# ❌ NEVER DO THIS - Missing authorization check
@app.route('/api/documents/<doc_id>')
def get_document(doc_id):
return Document.query.get(doc_id) # No ownership check!
# ✅ DO THIS INSTEAD - Verify ownership
def get_document(doc_id):
document = Document.query.get_or_404(doc_id)
if document.owner_id != current_user.id:
abort(403)
return document
3. Cryptography and Secrets Management
The Problem: AI models frequently copy insecure cryptographic patterns from training data: obsolete ciphers, incorrect modes, hardcoded keys, weak PRNGs, and custom cryptographic schemes. They also commonly suggest embedding secrets directly in code or configuration files.
Checklist
No hardcoded secrets: Search for and eliminate:
API keys embedded in source code
Database passwords in configuration files
Private keys in repositories
Authentication tokens in comments or documentation
Long hex/base64 strings that could be encoded secrets
Secure secrets management:
Use dedicated secrets managers (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Secret Manager)
Use environment variables as minimum acceptable practice (never commit .env files)
Implement secret rotation policies
Use separate secrets for different environments
Modern cryptographic algorithms:
Symmetric encryption: AES-256-GCM (authenticated encryption) or ChaCha20-Poly1305
Asymmetric encryption: RSA-2048+ (OAEP padding) or ECC (P-256, P-384)
Hashing: SHA-256, SHA-3, or BLAKE2/BLAKE3
Password hashing: Argon2id, bcrypt, or scrypt
Key exchange: ECDH, X25519
Avoid deprecated/weak algorithms:
Never use DES, 3DES, RC4, or AES-ECB
Avoid MD5 and SHA1 for security-sensitive operations
Don't use PKCS#1 v1.5 padding for RSA
Cryptographically secure random number generation:
Never use Math.random(), random module, or other non-cryptographic RNGs for security purposes
Proper key lengths and parameters:
AES: 256-bit keys
RSA: 2048-bit minimum (4096 recommended for long-term)
ECC: P-256 minimum
Argon2id: Appropriate memory, iterations, and parallelism for your hardware
Proper IV/nonce handling:
Use cryptographically secure random IVs for each encryption operation
Never reuse IVs with the same key (especially for GCM mode)
IVs don't need to be secret but must be unique
Never roll your own crypto:
Don't create custom encryption schemes
Don't implement your own authentication protocols
Don't create custom hash functions
Use well-vetted libraries and follow their documentation
Verification Steps
Secret Scanning: Use tools like truffleHog, git-secrets, or detect-secrets to find leaked secrets
Algorithm Audit: Verify all cryptographic algorithms are modern and properly used
Key Analysis: Check key generation, storage, and rotation practices
Randomness Test: Verify CSPRNG usage for all security-sensitive random values
Common AI Mistakes to Avoid
# ❌ NEVER DO THIS - Hardcoded secret
API_KEY = "sk_live_1234567890abcdef"
# ✅ DO THIS INSTEAD - Load from environment
import os
API_KEY = os.environ.get('API_KEY')
if not API_KEY:
raise ValueError("API_KEY environment variable is required")
# ❌ NEVER DO THIS - Weak encryption
encrypted = des.encrypt(data)
# ✅ DO THIS INSTEAD - Authenticated encryption
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher = Fernet(key)
encrypted = cipher.encrypt(data)
# ❌ NEVER DO THIS - Insecure random for security
import random
token = random.randint(100000, 999999)
# ✅ DO THIS INSTEAD - Cryptographically secure random
import secrets
token = secrets.randbelow(1000000)
# ❌ NEVER DO THIS - Custom crypto scheme
def custom_hash(data):
return data[::-1] + "salt"
# ✅ DO THIS INSTEAD - Use standard library
import hashlib
hashed = hashlib.sha256(data).hexdigest()
4. File Handling, Uploads, and Deserialization
The Problem: Documentation examples that AI learns from often omit path validation, file type checking, or size limits. This enables path traversal, remote code execution via deserialization, and Denial of Service through huge files. AI frequently uses dangerous APIs like pickle.loads() or unserialize() on untrusted data.
Checklist
Path traversal prevention:
Normalize all file paths derived from user input
Restrict file access to allowlisted directories
Use chroot jails or containerization where appropriate
Validate that resolved paths stay within allowed boundaries
Strip or reject path traversal sequences (../, ..\, null bytes)
Secure file uploads:
Validate file extensions against allowlists, not denylists
Verify MIME types match actual file content (magic bytes)
Scan uploaded files for malware
Limit file sizes and upload counts per request
Store uploads outside web root or use safe serving mechanisms
Rename files with random names to prevent execution attacks
Remove or sanitize metadata that could leak sensitive information
Deserialization security:
Never deserialize untrusted data using pickle, marshal, or language-specific unsafe deserialization
Use safe serialization formats: JSON, MessagePack, Protocol Buffers
If object deserialization is necessary, implement strict type allowlists
Use schema validation for all deserialized data
Consider signing serialized data to prevent tampering
File permission security:
Set least-privilege file permissions (never world-writable)
Use separate system users for file operations
Implement proper cleanup of temporary files
Secure file deletion when required
Verification Steps
Path Traversal Test: Attempt to access files outside allowed directories using ../, null bytes, Unicode normalization attacks
Deserialization Test: Attempt deserialization attacks with malicious payloads
File Permission Audit: Verify file and directory permissions are appropriate
Common AI Mistakes to Avoid
# ❌ NEVER DO THIS - Path traversal vulnerability
filename = request.args.get('file')
with open(f"/uploads/{filename}", 'r') as f:
content = f.read()
# ✅ DO THIS INSTEAD - Safe path handling
import os
from pathlib import Path
upload_dir = Path("/uploads").resolve()
filename = request.args.get('file')
# Sanitize and validate
safe_filename = os.path.basename(filename)
file_path = (upload_dir / safe_filename).resolve()
# Ensure the resolved path is within upload_dir
if not str(file_path).startswith(str(upload_dir)):
abort(403)
# ❌ NEVER DO THIS - Unsafe deserialization
import pickle
data = pickle.loads(untrusted_input)
# ✅ DO THIS INSTEAD - Safe deserialization
import json
data = json.loads(untrusted_input)
# Validate against schema
if not validate_json_schema(data, SCHEMA):
raise ValueError("Invalid data format")
# ❌ NEVER DO THIS - Insecure file upload
file = request.files['document']
file.save(f"/uploads/{file.filename}")
// ❌ NEVER DO THIS - Extension validation bypass
const allowedExtensions = ['.jpg', '.png'];
if (allowedExtensions.includes(path.extname(filename))) {
// This can be bypassed with double extensions or null bytes
}
// ✅ DO THIS INSTEAD - Comprehensive validation
const allowedTypes = ['image/jpeg', 'image/png'];
const maxSize = 5 * 1024 * 1024; // 5MB
if (!allowedTypes.includes(file.mimetype)) {
throw new Error('Invalid file type');
}
if (file.size > maxSize) {
throw new Error('File too large');
}
// Verify magic bytes match MIME type
const magic = file.buffer.slice(0, 4);
if (!isValidMagicBytes(magic, file.mimetype)) {
throw new Error('File content does not match type');
}
5. Secure Configuration and Dependency Management
The Problem: AI frequently proposes insecure example configurations: CORS set to *, disabled TLS verification, disabled CSRF protection, or verbose debug logging in production. AI may also "hallucinate" packages that don't exist or suggest typosquatted/obsoleted dependencies.
Checklist
Secure CORS configuration:
Never use * in production (only for specific development scenarios)
Explicitly define allowed origins
Limit allowed methods and headers
Set appropriate maxAge for preflight caching
Consider credentials handling carefully
TLS/SSL security:
Always enforce HTTPS in production
Use TLS 1.2 or higher (disable SSLv3, TLS 1.0, TLS 1.1)
Use strong cipher suites
Implement proper certificate validation
Never disable certificate verification "to make it work"
Security headers:
Content Security Policy (CSP)
X-Content-Type-Options: nosniff
X-Frame-Options or CSP frame-ancestors
Strict-Transport-Security (HSTS)
Referrer-Policy
Permissions-Policy
CSRF protection:
Enable CSRF tokens for state-changing operations
Use double-submit cookie pattern or synchronizer token pattern
Validate Origin/Referer headers as additional protection
Consider SameSite cookies
Debug mode and information disclosure:
Disable debug mode in production
Disable verbose error messages that expose stack traces
Disable server version banners
Remove default credentials and sample data
Disable auto-reload and hot-reload in production
Secure logging:
Never log secrets, tokens, passwords, or PII (Personally Identifiable Information)
Use structured logging with appropriate levels
Implement log rotation and retention policies
Protect log files with appropriate permissions
Consider log aggregation with security monitoring
Dependency security:
Verify all suggested packages exist and are legitimate
Check for typosquatting attacks (slight misspellings of popular packages)
Use lockfiles (package-lock.json, yarn.lock, poetry.lock, Cargo.lock, etc.)
Regularly audit dependencies for known vulnerabilities
Keep dependencies updated
Minimize dependency count (reduce attack surface)
Container and runtime security:
Run containers as non-root user
Use minimal base images (distroless, Alpine, scratch)
Implement read-only filesystems where possible
Use security contexts and capabilities dropping
Network segmentation and firewall rules
Resource limits (CPU, memory, file descriptors)
Verification Steps
Security Headers Test: Use tools like securityheaders.com to verify header configuration
Configuration Audit: Review all configuration files for insecure defaults
Dependency Scan: Run SCA tools (Snyk, Dependabot, npm audit, pip-audit)
Container Scan: Use tools like Trivy, Clair, or Grype to scan container images
Common AI Mistakes to Avoid
# ❌ NEVER DO THIS - Insecure CORS
CORS(app, resources={r"/*": {"origins": "*"}})
# ✅ DO THIS INSTEAD - Explicit origins
CORS(app, resources={
r"/api/*": {
"origins": ["https://app.example.com", "https://admin.example.com"],
"methods": ["GET", "POST"],
"allow_headers": ["Content-Type", "Authorization"]
}
})
# ❌ NEVER DO THIS - Disabled TLS verification
requests.get(url, verify=False)
# ✅ DO THIS INSTEAD - Proper TLS configuration
requests.get(url, verify=True) # Default, verify certificates
# ❌ NEVER DO THIS - Debug mode in production
app.run(debug=True)
# ✅ DO THIS INSTEAD - Environment-based configuration
debug = os.environ.get('FLASK_ENV') == 'development'
app.run(debug=debug)
# ❌ NEVER DO THIS - Logging sensitive data
logger.info(f"User login: {username}, password: {password}")
// ❌ NEVER DO THIS - Information disclosure in errors
app.use((err, req, res, next) => {
res.status(500).json({ error: err.stack });
});
// ✅ DO THIS INSTEAD - Safe error handling
app.use((err, req, res, next) => {
console.error(err); // Log internally
res.status(500).json({ error: 'Internal server error' }); // Generic public message
});
6. Business Logic and Contextual Security
The Problem: AI doesn't understand your business rules, threat model, or compliance requirements. It makes dangerous assumptions like "the input will always be valid" or "only internal users will call this API." This leads to logic vulnerabilities that aren't syntactically obvious.
Use Data Transfer Objects (DTOs) to control exposed data
Consider GraphQL query depth and complexity limiting
Race condition protection:
Use transactions for multi-step operations
Implement proper locking mechanisms
Handle concurrent modifications gracefully
Use optimistic or pessimistic locking as appropriate
Business logic validation:
Validate business rules, not just data types
Check for impossible states (negative balances, future dates in past, etc.)
Implement workflow state validation
Validate resource ownership and availability
Verification Steps
Abuse Case Analysis: Think like an attacker—how could this feature be misused?
Boundary Testing: Test edge cases and business rule boundaries
Race Condition Testing: Execute concurrent requests to identify timing issues
Data Exposure Audit: Review all API responses for over-exposure
Common AI Mistakes to Avoid
# ❌ NEVER DO THIS - Client-controlled authorization
role = request.json.get('role') # User can set their own role!
if role == 'admin':
# grant admin access
# ✅ DO THIS INSTEAD - Server-side role verification
user = get_current_user()
if not user.has_permission('admin'):
abort(403)
# ❌ NEVER DO THIS - Sensitive operation without confirmation
@app.route('/api/change-email', methods=['POST'])
def change_email():
current_user.email = request.json['new_email']
db.session.commit()
return {'status': 'success'}
# ✅ DO THIS INSTEAD - Require verification
def change_email():
new_email = request.json['new_email']
token = generate_verification_token(new_email)
send_verification_email(new_email, token)
return {'status': 'verification_sent'}
// ❌ NEVER DO THIS - Over-exposure of data
app.get('/api/users', (req, res) => {
const users = await User.findAll();
res.json(users); // Returns all fields including hashed passwords!
});
// ✅ DO THIS INSTEAD - Selective field exposure
app.get('/api/users', async (req, res) => {
const users = await User.findAll({
attributes: ['id', 'username', 'email'] // Explicitly choose fields
});
res.json(users);
});
7. Error Handling and Information Disclosure
The Problem: AI-generated code often lacks proper error handling or exposes sensitive information in error messages, stack traces, or logs. This aids attackers in reconnaissance and exploitation.
Checklist
Safe error responses:
Return generic error messages to clients
Don't expose stack traces, internal paths, or database details
Use standardized error response formats
Include error codes for support without revealing implementation
Proper exception handling:
Catch specific exceptions, not broad except: or catch (Exception e)
Handle errors gracefully without crashing
Ensure resources are cleaned up in finally blocks
Don't swallow exceptions silently
Fail securely:
Default to "deny" when errors occur
Don't bypass security controls due to exceptions
Validate state after error recovery
Log security-relevant errors
Information leakage prevention:
Remove version numbers from headers and error pages
Don't reveal user enumeration (e.g., "password incorrect" vs "user not found")
Sanitize error messages of sensitive data
Be careful with 404 vs 403 responses (don't reveal resource existence)
Verification Steps
Error Response Analysis: Trigger errors and examine responses
Stack Trace Exposure: Verify stack traces aren't returned in production
Information Leakage Test: Attempt to extract system information through errors
8. API Security
The Problem: APIs are increasingly targeted and AI-generated code often lacks proper API security controls like rate limiting, authentication, input validation, and output encoding.
Checklist
API authentication:
Implement proper authentication for all endpoints
Use API keys, OAuth 2.0, or JWT appropriately
Secure API key transmission (headers, not URL/query params)
Implement key rotation mechanisms
API rate limiting:
Implement tiered rate limits (different for authenticated vs anonymous)
Use appropriate rate limit windows
Return proper 429 status codes
Include rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining)
API versioning:
Version your APIs to allow graceful deprecation
Use URL versioning (/v1/, /v2/) or header versioning
Document breaking changes
API documentation security:
Don't expose internal endpoints in public documentation
API Authentication Test: Attempt to access protected endpoints without authentication
Rate Limiting Test: Exceed rate limits and verify behavior
API Discovery: Enumerate endpoints and verify no hidden/internal APIs are exposed
Implementation Workflow
Phase 1: Design
Define threat model and security requirements
Identify sensitive data and operations
Design authentication and authorization architecture
Plan security controls for each component
Phase 2: Development
Apply secure coding patterns from this skill
Implement input validation at all entry points
Use parameterized queries and safe APIs
Configure security headers and CORS properly
Implement proper error handling
Phase 3: Testing
Run automated security scans (SAST, SCA)
Perform manual code review with this checklist
Conduct penetration testing
Test with fuzzing and injection payloads
Verify business logic security
Phase 4: Deployment
Secure configuration management
Enable security monitoring and logging
Implement incident response procedures
Plan for security updates and patches
Compliance and Standards
OWASP Top 10
Stay current with the latest OWASP Top 10 vulnerabilities and ensure your applications are protected against them.
CWE/SANS Top 25
Address the most dangerous software weaknesses identified by MITRE and SANS.
Industry-Specific Standards
PCI-DSS: For payment card data
HIPAA: For healthcare data
GDPR: For EU personal data
SOC 2: For service organizations
When to Use This Skill
Before writing any code: Review security requirements and threat model
During code generation: Ensure AI-generated code follows security best practices
During code review: Verify code against this comprehensive checklist
During security audits: Use as a systematic guide for vulnerability assessment
During incident response: Identify root causes and prevent recurrence
During security training: Educate developers on secure coding practices
Summary
Security is not a feature—it's a foundation. AI-generated code requires extra scrutiny because models prioritize functionality and aesthetics over security. This skill provides the guardrails, checklists, and verification steps needed to ensure your code is secure by design, not by accident, the examples provided in this place are from python but you need to adapt the logic from python to the codebase language.
Remember: Trust but verify. Always assume AI-generated code contains vulnerabilities until proven otherwise through rigorous review and testing.
This skill should be consulted for every code generation task, every code review, and every security audit. Security is everyone's responsibility.
1---2name: secure-coding-cybersecurity3description: Expert guidance on secure coding practices, focusing on preventing common security errors made by AI during code generation. Use for: auditing AI-generated code, implementing secure design patterns, and ensuring code follows OWASP Top 10 standards. Covers input validation, authentication, cryptography, file handling, secure configuration, and business logic security.4---56# Secure Coding & Cybersecurity Skill78## Vision and Purpose910This skill establishes security as a first-class citizen in code generation and review. It recognizes that AI-generated code often prioritizes functionality over security, inheriting and propagating vulnerabilities from training data. This skill provides comprehensive guardrails, checklists, and verification steps to ensure all code—especially AI-generated—is robust, secure, and follows industry best practices.1112## Critical Understanding: Why AI Code is Often Insecure1314AI models optimize for "working code" and "correct-looking output" before "secure and robust code." This introduces classic vulnerabilities at concerning rates:1516### Root Causes of AI Security Failures17181. **Functionality over Security**: If the prompt doesn't explicitly demand security, the model prioritizes the shortest solution even if it uses `eval()`, SQL string concatenation, or hardcoded keys.19202. **Learning from Insecure Examples**: A significant portion of publicly available code contains bad practices (hardcoded secrets, weak encryption, missing validation), and models reproduce these patterns.21223. **Lack of Context Awareness**: AI doesn't understand your business rules, threat model, or compliance requirements (PCI-DSS, HIPAA, GDPR), filling gaps with dangerous assumptions.23244. **High CWE Rates in Studies**: Empirical research consistently finds serious vulnerabilities (SQLi, XSS, buffer overflows, crypto misuse, hardcoded credentials) in AI-generated code samples.2526## The Security Non-Negotiables2728These rules must NEVER be violated, regardless of convenience or "example purposes":29301. **Never Prioritize Simplicity Over Security**: Do not provide "clean" examples that omit input validation or use insecure defaults, even with disclaimers.31322. **Treat AI Output as Untrusted**: Always audit AI-generated snippets for hallucinated libraries, outdated patterns, and missing security controls.33343. **Fail Closed**: All logic must default to "Access Denied" if an exception occurs, validation fails, or state is unclear.35364. **No Hardcoded Secrets**: Never suggest code with hardcoded API keys, passwords, tokens, or cryptographic keys. Always use environment variables, secret managers, or secure vaults.37385. **Parameterized Everything**: Never use string concatenation or formatting for SQL queries, OS commands, HTML rendering, or LDAP filters.39406. **Validate All Inputs**: Every piece of external data must be validated and sanitized before use.41427. **Defense in Depth**: Never rely on a single security control; implement multiple layers of protection.4344## Comprehensive Security Checklist4546### 1. Input Validation and Injection Prevention4748**The Problem**: AI frequently omits input validation and sanitization unless explicitly requested, leading to CWE-20 (Improper Input Validation) and the entire injection vulnerability family (SQLi, XSS, OS Command Injection, LDAP Injection).4950**Research Finding**: Multiple studies identify SQL injection, XSS, and OS command injection as recurrent vulnerabilities in LLM-generated code.5152#### Checklist5354- [ ] **Validate and normalize ALL user input** before use, including:55 - Query parameters (URL parameters)56 - Request body (JSON, form data)57 - Headers (including custom headers)58 - Path parameters59 - File uploads60 - WebSocket messages61 - GraphQL inputs6263- [ ] **Use allowlists over denylists**: Define what is permitted rather than trying to block what is malicious. Use strict type checking, enum validation, and schema validation.6465- [ ] **Parameterized queries ONLY**: Never concatenate strings to build SQL queries, shell commands, LDAP filters, XPath expressions, or NoSQL queries. Always use:66 - Prepared statements with bound parameters67 - ORM query builders with parameterized methods68 - Safe API abstractions that prevent injection6970- [ ] **XSS Prevention**: Escape or sanitize all data before rendering in HTML contexts:71 - Use auto-escaping template engines72 - Apply context-appropriate encoding (HTML, JavaScript, CSS, URL)73 - Avoid `innerHTML`, `document.write`, and similar dangerous APIs74 - Implement Content Security Policy (CSP) headers7576- [ ] **Disable dangerous evaluation**: Never use `eval()`, `Function()`, `exec()`, `child_process.exec()`, `Runtime.exec()`, `os.system()`, or similar on user-controlled data. If dynamic execution is absolutely necessary, use strict sandboxing and allowlists.7778- [ ] **Strict regex validation**: When using regular expressions for validation:79 - Prefer exact match patterns (`^pattern$`) over partial matches80 - Avoid overly permissive patterns81 - Be aware of ReDoS (Regular Expression Denial of Service) vulnerabilities8283#### Verification Steps8485Before considering input handling complete:86871. **Fuzz Test**: Test with unexpected inputs (null, empty strings, very long strings, special characters, Unicode, binary data)882. **Injection Test**: Attempt SQL, NoSQL, command, and XSS injection payloads893. **Boundary Test**: Test at and beyond length limits, type boundaries, and range limits904. **Negative Test**: Ensure invalid inputs are rejected with appropriate errors9192#### Common AI Mistakes to Avoid9394```python95# ❌ NEVER DO THIS - SQL Injection vulnerability96query = f"SELECT * FROM users WHERE id = {user_id}"97cursor.execute(query)9899# ✅ DO THIS INSTEAD - Parameterized query100query = "SELECT * FROM users WHERE id = ?"101cursor.execute(query, (user_id,))102103# ❌ NEVER DO THIS - XSS vulnerability104element.innerHTML = userInput105106// ❌ NEVER DO THIS - Command Injection107const output = exec(`ls ${userInput}`);108109// ✅ DO THIS INSTEAD - Safe command execution with allowlist110const allowedCommands = ['list', 'status'];111if (allowedCommands.includes(userInput)) {112 const output = execFile('ls', [safePath]);113}114```115116---117118### 2. Authentication, Authorization, and Session Management119120**The Problem**: AI generates authentication flows that "pass happy path tests" but ignore critical security details like rate limiting, constant-time comparison, or fine-grained authorization controls. This enables brute-force attacks, privilege escalation, and API abuse.121122#### Checklist123124- [ ] **Secure password storage**:125 - Use modern, memory-hard algorithms: Argon2id (recommended), bcrypt, or scrypt126 - Never use MD5, SHA1, SHA256 for password hashing (they're too fast)127 - Always use unique salts per password128 - Configure appropriate cost factors/work factors129130- [ ] **Constant-time comparisons**: Compare tokens, passwords, and API keys using constant-time comparison functions to prevent timing attacks:131 - Python: `hmac.compare_digest()`132 - Node.js: `crypto.timingSafeEqual()`133 - Java: `MessageDigest.isEqual()`134135- [ ] **Rate limiting and brute-force protection**:136 - Implement rate limiting on login endpoints, password reset, OTP verification, and sensitive APIs137 - Use progressive delays for failed attempts138 - Consider CAPTCHA after multiple failures139 - Implement account lockout policies (with unlock mechanisms)140141- [ ] **Authorization on every endpoint**:142 - Verify ownership and permissions on every request, not just authentication143 - Check for IDOR (Insecure Direct Object Reference) vulnerabilities144 - Validate that users can only access their own resources145 - Implement attribute-based access control (ABAC) where appropriate146147- [ ] **Secure session management**:148 - Use cryptographically secure random session IDs149 - Implement reasonable session timeouts150 - Support session revocation and rotation151 - Regenerate session IDs on privilege changes (login, password change, role change)152153- [ ] **Secure cookie configuration**:154 - Set `HttpOnly` flag (prevents JavaScript access)155 - Set `Secure` flag (HTTPS only)156 - Set `SameSite` attribute (Strict or Lax)157 - Use appropriate `Max-Age` or `Expires`158 - Consider `__Host-` prefix for additional protection159160- [ ] **JWT security**:161 - Use strong signing algorithms (RS256, ES256, HS256 with strong secrets)162 - Never use "none" algorithm or weak secrets163 - Set short expiration times164 - Include token rotation and revocation mechanisms165 - Store tokens securely (not in localStorage for sensitive apps)166167- [ ] **Password reset security**:168 - Use cryptographically secure random tokens with high entropy169 - Implement single-use tokens with short expiration170 - Do not reveal whether an email exists in the system (privacy protection)171 - Invalidate existing tokens when new ones are requested172 - Require re-authentication after password reset173174- [ ] **Multi-factor authentication (MFA)**:175 - Support TOTP (Time-based One-Time Password)176 - Support WebAuthn/FIDO2 for strong authentication177 - Enforce MFA for privileged accounts178 - Implement backup codes securely179180#### Verification Steps1811821. **Brute Force Test**: Attempt to guess passwords, session IDs, and tokens1832. **Timing Attack Test**: Measure response times for different inputs1843. **Authorization Test**: Try to access other users' resources1854. **Session Fixation Test**: Verify session ID changes on login1865. **Token Analysis**: Check JWT headers and payloads for security issues187188#### Common AI Mistakes to Avoid189190```python191# ❌ NEVER DO THIS - Insecure password hashing192hashed = hashlib.md5(password.encode()).hexdigest()193194# ✅ DO THIS INSTEAD - Secure password hashing195hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))196197# ❌ NEVER DO THIS - Timing attack vulnerability198if token == stored_token:199 # authenticate200201# ✅ DO THIS INSTEAD - Constant-time comparison202if hmac.compare_digest(token, stored_token):203 # authenticate204205# ❌ NEVER DO THIS - No rate limiting206@app.route('/login', methods=['POST'])207def login():208 # authenticate209210# ✅ DO THIS INSTEAD - Rate limiting211@limiter.limit("5 per minute")212@app.route('/login', methods=['POST'])213def login():214 # authenticate215216# ❌ NEVER DO THIS - Missing authorization check217@app.route('/api/documents/<doc_id>')218def get_document(doc_id):219 return Document.query.get(doc_id) # No ownership check!220221# ✅ DO THIS INSTEAD - Verify ownership222def get_document(doc_id):223 document = Document.query.get_or_404(doc_id)224 if document.owner_id != current_user.id:225 abort(403)226 return document227```228229---230231### 3. Cryptography and Secrets Management232233**The Problem**: AI models frequently copy insecure cryptographic patterns from training data: obsolete ciphers, incorrect modes, hardcoded keys, weak PRNGs, and custom cryptographic schemes. They also commonly suggest embedding secrets directly in code or configuration files.234235#### Checklist236237- [ ] **No hardcoded secrets**: Search for and eliminate:238 - API keys embedded in source code239 - Database passwords in configuration files240 - Private keys in repositories241 - Authentication tokens in comments or documentation242 - Long hex/base64 strings that could be encoded secrets243244- [ ] **Secure secrets management**:245 - Use dedicated secrets managers (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Secret Manager)246 - Use environment variables as minimum acceptable practice (never commit `.env` files)247 - Implement secret rotation policies248 - Use separate secrets for different environments249250- [ ] **Modern cryptographic algorithms**:251 - Symmetric encryption: AES-256-GCM (authenticated encryption) or ChaCha20-Poly1305252 - Asymmetric encryption: RSA-2048+ (OAEP padding) or ECC (P-256, P-384)253 - Hashing: SHA-256, SHA-3, or BLAKE2/BLAKE3254 - Password hashing: Argon2id, bcrypt, or scrypt255 - Key exchange: ECDH, X25519256257- [ ] **Avoid deprecated/weak algorithms**:258 - Never use DES, 3DES, RC4, or AES-ECB259 - Avoid MD5 and SHA1 for security-sensitive operations260 - Don't use PKCS#1 v1.5 padding for RSA261262- [ ] **Cryptographically secure random number generation**:263 - Python: `secrets.token_hex()`, `secrets.token_urlsafe()`, `secrets.randbits()`264 - Node.js: `crypto.randomBytes()`, `crypto.randomUUID()`265 - Java: `SecureRandom`266 - Never use `Math.random()`, `random` module, or other non-cryptographic RNGs for security purposes267268- [ ] **Proper key lengths and parameters**:269 - AES: 256-bit keys270 - RSA: 2048-bit minimum (4096 recommended for long-term)271 - ECC: P-256 minimum272 - Argon2id: Appropriate memory, iterations, and parallelism for your hardware273274- [ ] **Proper IV/nonce handling**:275 - Use cryptographically secure random IVs for each encryption operation276 - Never reuse IVs with the same key (especially for GCM mode)277 - IVs don't need to be secret but must be unique278279- [ ] **Never roll your own crypto**:280 - Don't create custom encryption schemes281 - Don't implement your own authentication protocols282 - Don't create custom hash functions283 - Use well-vetted libraries and follow their documentation284285#### Verification Steps2862871. **Secret Scanning**: Use tools like `truffleHog`, `git-secrets`, or `detect-secrets` to find leaked secrets2882. **Algorithm Audit**: Verify all cryptographic algorithms are modern and properly used2893. **Key Analysis**: Check key generation, storage, and rotation practices2904. **Randomness Test**: Verify CSPRNG usage for all security-sensitive random values291292#### Common AI Mistakes to Avoid293294```python295# ❌ NEVER DO THIS - Hardcoded secret296API_KEY = "sk_live_1234567890abcdef"297298# ✅ DO THIS INSTEAD - Load from environment299import os300API_KEY = os.environ.get('API_KEY')301if not API_KEY:302 raise ValueError("API_KEY environment variable is required")303304# ❌ NEVER DO THIS - Weak encryption305encrypted = des.encrypt(data)306307# ✅ DO THIS INSTEAD - Authenticated encryption308from cryptography.fernet import Fernet309key = Fernet.generate_key()310cipher = Fernet(key)311encrypted = cipher.encrypt(data)312313# ❌ NEVER DO THIS - Insecure random for security314import random315token = random.randint(100000, 999999)316317# ✅ DO THIS INSTEAD - Cryptographically secure random318import secrets319token = secrets.randbelow(1000000)320321# ❌ NEVER DO THIS - Custom crypto scheme322def custom_hash(data):323 return data[::-1] + "salt"324325# ✅ DO THIS INSTEAD - Use standard library326import hashlib327hashed = hashlib.sha256(data).hexdigest()328```329330---331332### 4. File Handling, Uploads, and Deserialization333334**The Problem**: Documentation examples that AI learns from often omit path validation, file type checking, or size limits. This enables path traversal, remote code execution via deserialization, and Denial of Service through huge files. AI frequently uses dangerous APIs like `pickle.loads()` or `unserialize()` on untrusted data.335336#### Checklist337338- [ ] **Path traversal prevention**:339 - Normalize all file paths derived from user input340 - Restrict file access to allowlisted directories341 - Use `chroot` jails or containerization where appropriate342 - Validate that resolved paths stay within allowed boundaries343 - Strip or reject path traversal sequences (`../`, `..\`, null bytes)344345- [ ] **Secure file uploads**:346 - Validate file extensions against allowlists, not denylists347 - Verify MIME types match actual file content (magic bytes)348 - Scan uploaded files for malware349 - Limit file sizes and upload counts per request350 - Store uploads outside web root or use safe serving mechanisms351 - Rename files with random names to prevent execution attacks352 - Remove or sanitize metadata that could leak sensitive information353354- [ ] **Deserialization security**:355 - Never deserialize untrusted data using pickle, marshal, or language-specific unsafe deserialization356 - Use safe serialization formats: JSON, MessagePack, Protocol Buffers357 - If object deserialization is necessary, implement strict type allowlists358 - Use schema validation for all deserialized data359 - Consider signing serialized data to prevent tampering360361- [ ] **File permission security**:362 - Set least-privilege file permissions (never world-writable)363 - Use separate system users for file operations364 - Implement proper cleanup of temporary files365 - Secure file deletion when required366367#### Verification Steps3683691. **Path Traversal Test**: Attempt to access files outside allowed directories using `../`, null bytes, Unicode normalization attacks3702. **Upload Security Test**: Try uploading executable files, scripts, oversized files, and malicious content3713. **Deserialization Test**: Attempt deserialization attacks with malicious payloads3724. **File Permission Audit**: Verify file and directory permissions are appropriate373374#### Common AI Mistakes to Avoid375376```python377# ❌ NEVER DO THIS - Path traversal vulnerability378filename = request.args.get('file')379with open(f"/uploads/{filename}", 'r') as f:380 content = f.read()381382# ✅ DO THIS INSTEAD - Safe path handling383import os384from pathlib import Path385386upload_dir = Path("/uploads").resolve()387filename = request.args.get('file')388# Sanitize and validate389safe_filename = os.path.basename(filename)390file_path = (upload_dir / safe_filename).resolve()391392# Ensure the resolved path is within upload_dir393if not str(file_path).startswith(str(upload_dir)):394 abort(403)395396# ❌ NEVER DO THIS - Unsafe deserialization397import pickle398data = pickle.loads(untrusted_input)399400# ✅ DO THIS INSTEAD - Safe deserialization401import json402data = json.loads(untrusted_input)403# Validate against schema404if not validate_json_schema(data, SCHEMA):405 raise ValueError("Invalid data format")406407# ❌ NEVER DO THIS - Insecure file upload408file = request.files['document']409file.save(f"/uploads/{file.filename}")410411// ❌ NEVER DO THIS - Extension validation bypass412const allowedExtensions = ['.jpg', '.png'];413if (allowedExtensions.includes(path.extname(filename))) {414 // This can be bypassed with double extensions or null bytes415}416417// ✅ DO THIS INSTEAD - Comprehensive validation418const allowedTypes = ['image/jpeg', 'image/png'];419const maxSize = 5 * 1024 * 1024; // 5MB420421if (!allowedTypes.includes(file.mimetype)) {422 throw new Error('Invalid file type');423}424425if (file.size > maxSize) {426 throw new Error('File too large');427}428429// Verify magic bytes match MIME type430const magic = file.buffer.slice(0, 4);431if (!isValidMagicBytes(magic, file.mimetype)) {432 throw new Error('File content does not match type');433}434```435436---437438### 5. Secure Configuration and Dependency Management439440**The Problem**: AI frequently proposes insecure example configurations: CORS set to `*`, disabled TLS verification, disabled CSRF protection, or verbose debug logging in production. AI may also "hallucinate" packages that don't exist or suggest typosquatted/obsoleted dependencies.441442#### Checklist443444- [ ] **Secure CORS configuration**:445 - Never use `*` in production (only for specific development scenarios)446 - Explicitly define allowed origins447 - Limit allowed methods and headers448 - Set appropriate `maxAge` for preflight caching449 - Consider credentials handling carefully450451- [ ] **TLS/SSL security**:452 - Always enforce HTTPS in production453 - Use TLS 1.2 or higher (disable SSLv3, TLS 1.0, TLS 1.1)454 - Use strong cipher suites455 - Implement proper certificate validation456 - Never disable certificate verification "to make it work"457458- [ ] **Security headers**:459 - Content Security Policy (CSP)460 - X-Content-Type-Options: nosniff461 - X-Frame-Options or CSP frame-ancestors462 - Strict-Transport-Security (HSTS)463 - Referrer-Policy464 - Permissions-Policy465466- [ ] **CSRF protection**:467 - Enable CSRF tokens for state-changing operations468 - Use double-submit cookie pattern or synchronizer token pattern469 - Validate Origin/Referer headers as additional protection470 - Consider SameSite cookies471472- [ ] **Debug mode and information disclosure**:473 - Disable debug mode in production474 - Disable verbose error messages that expose stack traces475 - Disable server version banners476 - Remove default credentials and sample data477 - Disable auto-reload and hot-reload in production478479- [ ] **Secure logging**:480 - Never log secrets, tokens, passwords, or PII (Personally Identifiable Information)481 - Use structured logging with appropriate levels482 - Implement log rotation and retention policies483 - Protect log files with appropriate permissions484 - Consider log aggregation with security monitoring485486- [ ] **Dependency security**:487 - Verify all suggested packages exist and are legitimate488 - Check for typosquatting attacks (slight misspellings of popular packages)489 - Use lockfiles (package-lock.json, yarn.lock, poetry.lock, Cargo.lock, etc.)490 - Regularly audit dependencies for known vulnerabilities491 - Keep dependencies updated492 - Minimize dependency count (reduce attack surface)493494- [ ] **Container and runtime security**:495 - Run containers as non-root user496 - Use minimal base images (distroless, Alpine, scratch)497 - Implement read-only filesystems where possible498 - Use security contexts and capabilities dropping499 - Network segmentation and firewall rules500 - Resource limits (CPU, memory, file descriptors)501502#### Verification Steps5035041. **Security Headers Test**: Use tools like `securityheaders.com` to verify header configuration5052. **Configuration Audit**: Review all configuration files for insecure defaults5063. **Dependency Scan**: Run SCA tools (Snyk, Dependabot, npm audit, pip-audit)5074. **Container Scan**: Use tools like Trivy, Clair, or Grype to scan container images508509#### Common AI Mistakes to Avoid510511```python512# ❌ NEVER DO THIS - Insecure CORS513CORS(app, resources={r"/*": {"origins": "*"}})514515# ✅ DO THIS INSTEAD - Explicit origins516CORS(app, resources={517 r"/api/*": {518 "origins": ["https://app.example.com", "https://admin.example.com"],519 "methods": ["GET", "POST"],520 "allow_headers": ["Content-Type", "Authorization"]521 }522})523524# ❌ NEVER DO THIS - Disabled TLS verification525requests.get(url, verify=False)526527# ✅ DO THIS INSTEAD - Proper TLS configuration528requests.get(url, verify=True) # Default, verify certificates529530# ❌ NEVER DO THIS - Debug mode in production531app.run(debug=True)532533# ✅ DO THIS INSTEAD - Environment-based configuration534debug = os.environ.get('FLASK_ENV') == 'development'535app.run(debug=debug)536537# ❌ NEVER DO THIS - Logging sensitive data538logger.info(f"User login: {username}, password: {password}")539540// ❌ NEVER DO THIS - Information disclosure in errors541app.use((err, req, res, next) => {542 res.status(500).json({ error: err.stack });543});544545// ✅ DO THIS INSTEAD - Safe error handling546app.use((err, req, res, next) => {547 console.error(err); // Log internally548 res.status(500).json({ error: 'Internal server error' }); // Generic public message549});550```551552---553554### 6. Business Logic and Contextual Security555556**The Problem**: AI doesn't understand your business rules, threat model, or compliance requirements. It makes dangerous assumptions like "the input will always be valid" or "only internal users will call this API." This leads to logic vulnerabilities that aren't syntactically obvious.557558#### Checklist559560- [ ] **Document security assumptions**: Explicitly write down:561 - Who is calling the API (internal, external, authenticated, anonymous)562 - Where requests are coming from (IP ranges, geolocation)563 - What privileges callers have564 - What the input can contain (valid ranges, formats)565 - What the expected threat model is566567- [ ] **Beware of "fast paths"**: Review any logic that skips security controls under certain conditions:568 - "If the request has X header, skip Y validation"569 - "If the user is internal, skip Z check"570 - These can often be abused571572- [ ] **Server-side authorization**: Never rely on client-controlled data for authorization decisions:573 - Don't trust JWT claims without verification574 - Don't use client-provided role flags575 - Don't trust client-side validation576 - Always re-verify permissions server-side577578- [ ] **Sensitive operation protection**:579 - Require re-authentication for sensitive operations (email change, password change, role change, financial transactions)580 - Implement MFA for high-risk operations581 - Use confirmation mechanisms (email verification, OTP)582 - Log all sensitive operations with audit trails583584- [ ] **Data exposure review**:585 - Review all API responses for over-exposure of data586 - Don't expose internal fields (database IDs, internal flags, debug info)587 - Implement field-level access control588 - Use Data Transfer Objects (DTOs) to control exposed data589 - Consider GraphQL query depth and complexity limiting590591- [ ] **Race condition protection**:592 - Use transactions for multi-step operations593 - Implement proper locking mechanisms594 - Handle concurrent modifications gracefully595 - Use optimistic or pessimistic locking as appropriate596597- [ ] **Business logic validation**:598 - Validate business rules, not just data types599 - Check for impossible states (negative balances, future dates in past, etc.)600 - Implement workflow state validation601 - Validate resource ownership and availability602603#### Verification Steps6046051. **Abuse Case Analysis**: Think like an attacker—how could this feature be misused?6062. **Boundary Testing**: Test edge cases and business rule boundaries6073. **Race Condition Testing**: Execute concurrent requests to identify timing issues6084. **Data Exposure Audit**: Review all API responses for over-exposure609610#### Common AI Mistakes to Avoid611612```python613# ❌ NEVER DO THIS - Client-controlled authorization614role = request.json.get('role') # User can set their own role!615if role == 'admin':616 # grant admin access617618# ✅ DO THIS INSTEAD - Server-side role verification619user = get_current_user()620if not user.has_permission('admin'):621 abort(403)622623# ❌ NEVER DO THIS - Sensitive operation without confirmation624@app.route('/api/change-email', methods=['POST'])625def change_email():626 current_user.email = request.json['new_email']627 db.session.commit()628 return {'status': 'success'}629630# ✅ DO THIS INSTEAD - Require verification631def change_email():632 new_email = request.json['new_email']633 token = generate_verification_token(new_email)634 send_verification_email(new_email, token)635 return {'status': 'verification_sent'}636637// ❌ NEVER DO THIS - Over-exposure of data638app.get('/api/users', (req, res) => {639 const users = await User.findAll();640 res.json(users); // Returns all fields including hashed passwords!641});642643// ✅ DO THIS INSTEAD - Selective field exposure644app.get('/api/users', async (req, res) => {645 const users = await User.findAll({646 attributes: ['id', 'username', 'email'] // Explicitly choose fields647 });648 res.json(users);649});650```651652---653654### 7. Error Handling and Information Disclosure655656**The Problem**: AI-generated code often lacks proper error handling or exposes sensitive information in error messages, stack traces, or logs. This aids attackers in reconnaissance and exploitation.657658#### Checklist659660- [ ] **Safe error responses**: 661 - Return generic error messages to clients662 - Don't expose stack traces, internal paths, or database details663 - Use standardized error response formats664 - Include error codes for support without revealing implementation665666- [ ] **Proper exception handling**:667 - Catch specific exceptions, not broad `except:` or `catch (Exception e)`668 - Handle errors gracefully without crashing669 - Ensure resources are cleaned up in finally blocks670 - Don't swallow exceptions silently671672- [ ] **Fail securely**:673 - Default to "deny" when errors occur674 - Don't bypass security controls due to exceptions675 - Validate state after error recovery676 - Log security-relevant errors677678- [ ] **Information leakage prevention**:679 - Remove version numbers from headers and error pages680 - Don't reveal user enumeration (e.g., "password incorrect" vs "user not found")681 - Sanitize error messages of sensitive data682 - Be careful with 404 vs 403 responses (don't reveal resource existence)683684#### Verification Steps6856861. **Error Response Analysis**: Trigger errors and examine responses6872. **Stack Trace Exposure**: Verify stack traces aren't returned in production6883. **Information Leakage Test**: Attempt to extract system information through errors689690---691692### 8. API Security693694**The Problem**: APIs are increasingly targeted and AI-generated code often lacks proper API security controls like rate limiting, authentication, input validation, and output encoding.695696#### Checklist697698- [ ] **API authentication**:699 - Implement proper authentication for all endpoints700 - Use API keys, OAuth 2.0, or JWT appropriately701 - Secure API key transmission (headers, not URL/query params)702 - Implement key rotation mechanisms703704- [ ] **API rate limiting**:705 - Implement tiered rate limits (different for authenticated vs anonymous)706 - Use appropriate rate limit windows707 - Return proper 429 status codes708 - Include rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining)709710- [ ] **API versioning**:711 - Version your APIs to allow graceful deprecation712 - Use URL versioning (/v1/, /v2/) or header versioning713 - Document breaking changes714715- [ ] **API documentation security**:716 - Don't expose internal endpoints in public documentation717 - Remove sensitive examples from documentation718 - Secure API specification files719720- [ ] **Webhook security**:721 - Verify webhook signatures722 - Use HTTPS for webhook URLs723 - Implement replay attack prevention (timestamps, nonces)724 - Allowlist IP ranges if possible725726#### Verification Steps7277281. **API Authentication Test**: Attempt to access protected endpoints without authentication7292. **Rate Limiting Test**: Exceed rate limits and verify behavior7303. **API Discovery**: Enumerate endpoints and verify no hidden/internal APIs are exposed731732---733734## Implementation Workflow735736### Phase 1: Design7371. Define threat model and security requirements7382. Identify sensitive data and operations7393. Design authentication and authorization architecture7404. Plan security controls for each component741742### Phase 2: Development7431. Apply secure coding patterns from this skill7442. Implement input validation at all entry points7453. Use parameterized queries and safe APIs7464. Configure security headers and CORS properly7475. Implement proper error handling748749### Phase 3: Testing7501. Run automated security scans (SAST, SCA)7512. Perform manual code review with this checklist7523. Conduct penetration testing7534. Test with fuzzing and injection payloads7545. Verify business logic security755756### Phase 4: Deployment7571. Secure configuration management7582. Enable security monitoring and logging7593. Implement incident response procedures7604. Plan for security updates and patches761762## Compliance and Standards763764### OWASP Top 10765Stay current with the latest OWASP Top 10 vulnerabilities and ensure your applications are protected against them.766767### CWE/SANS Top 25768Address the most dangerous software weaknesses identified by MITRE and SANS.769770### Industry-Specific Standards771- **PCI-DSS**: For payment card data772- **HIPAA**: For healthcare data773- **GDPR**: For EU personal data774- **SOC 2**: For service organizations775776## When to Use This Skill777778- **Before writing any code**: Review security requirements and threat model779- **During code generation**: Ensure AI-generated code follows security best practices780- **During code review**: Verify code against this comprehensive checklist781- **During security audits**: Use as a systematic guide for vulnerability assessment782- **During incident response**: Identify root causes and prevent recurrence783- **During security training**: Educate developers on secure coding practices784785## Summary786787Security is not a feature—it's a foundation. AI-generated code requires extra scrutiny because models prioritize functionality and aesthetics over security. This skill provides the guardrails, checklists, and verification steps needed to ensure your code is secure by design, not by accident, the examples provided in this place are from python but you need to adapt the logic from python to the codebase language.788789Remember: **Trust but verify**. Always assume AI-generated code contains vulnerabilities until proven otherwise through rigorous review and testing.790791---792793*This skill should be consulted for every code generation task, every code review, and every security audit. Security is everyone's responsibility.*
Run npx skillmds@latest add b4san/secure-coding-cybersecurity in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Expert guidance on secure coding practices, focusing on preventing common security errors made by AI during code generation. Use for: auditing AI-generated code, implementing secure design patterns, and ensuring code follows OWASP Top 10 standards. Covers input validation, authentication, cryptography, file handling, secure configuration, and business logic security. It is listed under Security on SkillMD.
SkillMD's automated safety review verdict for this skill is PASS. Independent scanners report: SkillSpector: WARNING, Skill Scanner: WARNING. Capability flags: executes scripts, makes network calls, reads secrets. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
B4san (@b4san) published this skill. Their other Agent Skills are listed on their SkillMD profile.