diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..9f8ad30 Binary files /dev/null and b/.DS_Store differ diff --git a/.claude/.DS_Store b/.claude/.DS_Store new file mode 100644 index 0000000..31980e2 Binary files /dev/null and b/.claude/.DS_Store differ diff --git a/.claude/skills/security-review-swarm/SKILL.md b/.claude/skills/security-review-swarm/SKILL.md new file mode 100644 index 0000000..9b6c148 --- /dev/null +++ b/.claude/skills/security-review-swarm/SKILL.md @@ -0,0 +1,396 @@ +--- +name: security-review-swarm +description: Comprehensive security code review using parallel agent swarms. Use this skill when performing security audits, vulnerability assessments, or pre-deployment security reviews on codebases. Triggers include: "security review", "security audit", "vulnerability scan", "find vulnerabilities", "check for security issues", "pentest the code", "audit authentication", "review for injection", "check for XSS", "credential scan", or any request involving security analysis of code. Supports both quick breadth scans and deep audits using specialized parallel agents for secrets, injection, XSS, authentication, cryptography, input validation, and dependency analysis. +--- + +# Security Review Swarm + +Orchestrates parallel security review agents using Claude Code's TeammateTool and Task system for comprehensive vulnerability detection. + +## Usage Patterns + +``` +/security-review # Quick breadth review of staged/recent changes +/security-review src/ # Review specific directory (breadth) +/security-review --deep # Deep audit with parallel specialists +/security-review --deep src/auth/ # Deep audit of specific path +/security-review --full # Complete swarm: all specialists in parallel +``` + +## Review Modes + +| Mode | Agents | Patterns | Use Case | +|------|--------|----------|----------| +| **Quick** (default) | 1 | 25+ breadth | PRs, quick scans, daily reviews | +| **Deep** (`--deep`) | 1 | 7 critical depth | Auth, crypto, payments, pre-launch | +| **Full** (`--full`) | 7 parallel | All patterns | Complete security audit | + +## Orchestration Instructions + +### Mode 1: Quick Review (Default) + +Single-agent review using BREADTH patterns: + +1. Load `references/ANTI_PATTERNS_BREADTH.md` +2. Determine scope (file path, `git diff HEAD~1`, or `git diff --cached`) +3. Analyze against all 25+ patterns, prioritizing: + - §1: Secrets and Credentials + - §2: Injection (SQL, Command, NoSQL) + - §3: XSS (Reflected, Stored, DOM) + - §4: Authentication & Sessions +4. Report findings in standard format + +### Mode 2: Deep Review (`--deep`) + +Single-agent deep dive using DEPTH patterns: + +1. Load `references/ANTI_PATTERNS_DEPTH.md` +2. For each of the 7 critical patterns, check: + - Multiple manifestation examples + - Edge cases section + - Common mistakes section + - Detection hints +3. Include security checklists in report + +### Mode 3: Full Swarm Review (`--full`) + +Parallel specialist agents for comprehensive coverage: + +```pseudocode +// 1. Create review team +Teammate({ operation: "spawnTeam", team_name: "security-review-{timestamp}" }) + +// 2. Create task queue for findings aggregation +TaskCreate({ subject: "Aggregate Findings", description: "Collect all specialist reports" }) + +// 3. Spawn 7 parallel specialists +specialists = [ + {name: "secrets-scanner", focus: "Pattern 1: Hardcoded Secrets"}, + {name: "injection-hunter", focus: "Pattern 2: SQL/Command Injection"}, + {name: "xss-detector", focus: "Pattern 3: Cross-Site Scripting"}, + {name: "auth-auditor", focus: "Pattern 4: Authentication & Sessions"}, + {name: "crypto-reviewer", focus: "Pattern 5: Cryptographic Failures"}, + {name: "input-validator", focus: "Pattern 6: Input Validation"}, + {name: "dependency-checker", focus: "Pattern 7: Dependencies & Supply Chain"} +] + +FOR specialist IN specialists: + Task({ + team_name: team_name, + name: specialist.name, + subagent_type: "general-purpose", + prompt: buildSpecialistPrompt(specialist, targetPath, context), + run_in_background: true + }) + +// 4. Wait for all specialists to report +// 5. Synthesize findings into unified report +// 6. Cleanup team +``` + +## Specialist Prompts + +### Secrets Scanner Agent + +``` +You are a security specialist focused on credential and secrets exposure. + +SCOPE: {target_path} + +Review for Pattern 1 (Hardcoded Secrets) from the security anti-patterns guide: + +CHECK FOR: +1. API keys, tokens, passwords in source code +2. Database connection strings with embedded credentials +3. JWT secrets and signing keys +4. Private keys (RSA, EC, SSH) +5. OAuth client secrets (especially in frontend code) +6. AWS/GCP/Azure credentials +7. Secrets in CI/CD configs, Docker files, environment files +8. Credentials leaked in logs or error messages +9. Test credentials that could work in production +10. Secrets in URL query parameters + +DETECTION PATTERNS: +- Variables named: password, secret, key, token, credential, api_key +- Patterns: sk_live_, sk_test_, ghp_, gho_, AKIA, AIza +- Private key markers: -----BEGIN (RSA|EC|DSA|OPENSSH)?PRIVATE KEY----- +- Connection strings: (mysql|postgresql|mongodb|redis)://[^:]+:[^@]+@ + +Send findings to team-lead with: +- File path and line number +- CWE reference (CWE-798, CWE-259, CWE-321) +- Severity (Critical/High) +- Specific remediation +``` + +### Injection Hunter Agent + +``` +You are a security specialist focused on injection vulnerabilities. + +SCOPE: {target_path} + +Review for Pattern 2 (Injection) from the security anti-patterns guide: + +CHECK FOR: +1. SQL queries with string concatenation or interpolation +2. Dynamic table/column names without allowlist +3. ORDER BY, LIMIT clauses with user input +4. Shell commands constructed with user data +5. LDAP filter construction +6. XPath query building +7. NoSQL query injection ($ne, $gt operators from user input) +8. Template injection (SSTI) +9. Second-order injection (stored data used unsafely later) +10. ORM raw queries without parameterization + +DETECTION PATTERNS: +- String concat in queries: (SELECT|INSERT|UPDATE|DELETE).*(\+|concat|\${|f['"]) +- Shell with variables: (system|exec|subprocess).*(\+|\${) +- shell=True usage + +Send findings to team-lead with CWE-89, CWE-78, CWE-90, CWE-643 references. +``` + +### XSS Detector Agent + +``` +You are a security specialist focused on Cross-Site Scripting. + +SCOPE: {target_path} + +Review for Pattern 3 (XSS) from the security anti-patterns guide: + +CHECK FOR: +1. innerHTML, document.write with user data +2. React dangerouslySetInnerHTML without sanitization +3. Vue v-html directive with user input +4. Angular bypassSecurityTrust* usage +5. Template |safe, {{{ }}} (triple braces), <%- %> patterns +6. User input in HTML attributes (especially event handlers) +7. JavaScript context injection +8. URL context (javascript:, data: schemes) +9. CSS context injection +10. Missing Content-Security-Policy headers + +CONTEXT-SPECIFIC ENCODING CHECK: +- HTML body: < > & " ' +- Attributes: Above + ` = +- JavaScript: \\' \\" \\n \\x3c \\x3e +- URL: encodeURIComponent + +Send findings to team-lead with CWE-79, CWE-80, CWE-83 references. +``` + +### Auth Auditor Agent + +``` +You are a security specialist focused on authentication and session security. + +SCOPE: {target_path} + +Review for Pattern 4 (Authentication) from the security anti-patterns guide: + +CHECK FOR: +1. Weak password validation (length only, no breach check) +2. Predictable session tokens (sequential, timestamp-based) +3. Session not regenerated after login (fixation) +4. JWT "none" algorithm acceptance +5. Weak JWT secrets (< 256 bits) +6. Tokens in localStorage (XSS exposure) +7. Missing token expiration +8. No rate limiting on auth endpoints +9. Insecure password reset flows +10. Missing MFA for sensitive operations + +SESSION SECURITY: +- HttpOnly, Secure, SameSite cookie flags +- Session invalidation on logout +- Concurrent session handling + +Send findings to team-lead with CWE-287, CWE-384, CWE-613, CWE-307 references. +``` + +### Crypto Reviewer Agent + +``` +You are a security specialist focused on cryptographic implementations. + +SCOPE: {target_path} + +Review for Pattern 5 (Cryptographic Failures) from the security anti-patterns guide: + +CHECK FOR: +1. Deprecated algorithms (MD5, SHA1 for security, DES, RC4) +2. Hardcoded encryption keys +3. ECB mode usage (reveals patterns) +4. Missing or predictable IVs/nonces +5. Custom/"homegrown" crypto implementations +6. Math.random() for security tokens +7. Weak key derivation (direct hash vs PBKDF2/Argon2) +8. Insufficient key lengths (< 256 bits for symmetric) +9. Password storage without bcrypt/argon2 +10. Missing authenticated encryption (use GCM, not CBC alone) + +SECURE ALTERNATIVES: +- Passwords: bcrypt, Argon2id, scrypt +- Symmetric: AES-256-GCM, ChaCha20-Poly1305 +- Hashing: SHA-256, SHA-3, BLAKE2 +- Random: secrets module, crypto.randomBytes + +Send findings to team-lead with CWE-327, CWE-328, CWE-330, CWE-326 references. +``` + +### Input Validator Agent + +``` +You are a security specialist focused on input validation. + +SCOPE: {target_path} + +Review for Pattern 6 (Input Validation) from the security anti-patterns guide: + +CHECK FOR: +1. Client-side only validation +2. Missing type checking (especially for NoSQL) +3. No length limits (DoS via large inputs) +4. ReDoS patterns: (a+)+, (a*)* +5. Trusting external data without verification +6. Missing canonicalization before validation +7. Path traversal (../ in file paths) +8. Missing URL scheme validation +9. Accepting untrusted serialized data (pickle, eval) +10. XML without entity restrictions (XXE) + +VALIDATION ORDER: +1. Decode all encoding layers +2. Canonicalize (normalize unicode, resolve paths) +3. Validate against allowlist +4. Encode for output context + +Send findings to team-lead with CWE-20, CWE-22, CWE-1333 references. +``` + +### Dependency Checker Agent + +``` +You are a security specialist focused on supply chain and dependency security. + +SCOPE: {target_path} + +Review for Pattern 7 (Dependencies) from the security anti-patterns guide: + +CHECK FOR: +1. Hallucinated/non-existent packages +2. Typosquatting package names +3. Outdated dependencies with known CVEs +4. Unpinned dependency versions +5. Dependencies from untrusted sources +6. Excessive dependency permissions +7. Dev dependencies in production +8. Deprecated packages +9. Low-maintenance packages (last update > 2 years) +10. Suspicious post-install scripts + +VERIFY PACKAGES EXIST: +- npm: https://registry.npmjs.org/{package} +- PyPI: https://pypi.org/pypi/{package}/json +- Check download counts and maintenance status + +Send findings to team-lead with CWE-1357 (Slopsquatting) references. +``` + +## Report Format + +```markdown +## Security Review Results + +**Scope:** {files/directories reviewed} +**Mode:** {quick|deep|full} +**Agents:** {list of specialists if full mode} +**Duration:** {time taken} + +### Summary + +| Severity | Count | Categories | +|----------|-------|------------| +| Critical | X | Secrets, Injection | +| High | X | Auth, XSS | +| Medium | X | Config, Input | + +### Critical Issues +{Must fix before deployment} + +### High Priority +{Fix soon} + +### Medium Priority +{Address when convenient} + +### Findings by Category + +#### 1. Secrets & Credentials +[Findings from secrets-scanner] + +#### 2. Injection Vulnerabilities +[Findings from injection-hunter] + +... {continue for each category} + +### Good Practices Found +{Positive patterns already in place} + +--- + +### Detailed Findings + +#### {Issue Title} +- **File:** `path/to/file.ts:123` +- **CWE:** CWE-XXX (Name) +- **Severity:** Critical/High/Medium +- **Agent:** {specialist name} +- **Pattern:** Brief description +- **Code:** + ``` + {vulnerable code snippet} + ``` +- **Fix:** + ``` + {remediated code} + ``` +- **Reference:** ANTI_PATTERNS_{BREADTH|DEPTH}.md §{section} +``` + +## Auto-Escalation Rules + +Automatically use DEPTH patterns (even without `--deep`) when reviewing: + +- `**/auth/**`, `**/login/**`, `**/session/**` +- `**/payment/**`, `**/stripe/**`, `**/billing/**` +- `**/crypto/**`, `**/encrypt/**`, `**/token/**` +- Files containing: `password`, `secret`, `jwt`, `bcrypt`, `oauth` + +Automatically use FULL swarm (even without `--full`) when: + +- Reviewing > 50 files +- Pre-production/release audit requested +- Scope includes authentication + payments + API +- User mentions "comprehensive" or "complete" audit + +## Team Lifecycle + +```pseudocode +// Full swarm cleanup sequence +FOR specialist IN active_specialists: + Teammate({ operation: "requestShutdown", target_agent_id: specialist.name }) + // Wait for shutdown_approved message + +// Verify all shutdown before cleanup +Teammate({ operation: "cleanup" }) +``` + +## References + +- `references/ANTI_PATTERNS_BREADTH.md` - 25+ patterns, ~65K tokens +- `references/ANTI_PATTERNS_DEPTH.md` - 7 critical patterns with edge cases, ~100K tokens diff --git a/.claude/skills/security-review-swarm/references/ANTI_PATTERNS_BREADTH.md b/.claude/skills/security-review-swarm/references/ANTI_PATTERNS_BREADTH.md new file mode 100644 index 0000000..215304f --- /dev/null +++ b/.claude/skills/security-review-swarm/references/ANTI_PATTERNS_BREADTH.md @@ -0,0 +1,7315 @@ +--- +type: reference +title: AI Code Security Anti-Patterns - Breadth Version +created: 2026-01-18 +version: 1.0.0 +tags: + - security + - anti-patterns + - ai-generated-code + - llm + - secure-coding +related: + - "[[ANTI_PATTERNS_DEPTH]]" + - "[[Ranking-Matrix]]" + - "[[Pseudocode-Examples]]" +--- + +# AI Code Security Anti-Patterns +## Breadth Version - Comprehensive Coverage + +> **Purpose:** Security anti-patterns guide for AI-assisted code generation +> **Audience:** Any LLM system prompt, RAG system, or context file +> **Format:** Pseudocode examples (implement in your target language) +> **How to use:** Include in system prompt or reference during code generation + +--- + +## INSTRUCTIONS FOR AI/LLM + +This document contains security anti-patterns you MUST avoid when generating code. +Each section shows a VULNERABLE pattern (marked BAD) and a SECURE alternative (marked GOOD). +All examples are in PSEUDOCODE - implement the secure patterns in whatever language +the developer is using. When in doubt, choose the more secure option. + +**Key Statistics:** +- AI-generated code has an **86% XSS failure rate** (vs 31.6% human code) +- **5-21% of AI-suggested packages don't exist** (slopsquatting risk) +- AI code is **2.74x more likely** to have XSS vulnerabilities +- **21.7% hallucination rate** for package names in some domains +- SQL injection patterns appeared "thousands of times" in AI training data + +**Before generating any code:** +1. Never hardcode credentials, API keys, or secrets +2. Always parameterize database queries +3. Validate and sanitize all user input +4. Use cryptographically secure random for security tokens +5. Verify packages exist before suggesting imports +6. Encode output for the appropriate context (HTML, URL, JS) + +--- + +## Quick Reference Table + +| Pattern | CWE | Severity | Quick Fix | +|---------|-----|----------|-----------| +| Hallucinated Packages | CWE-1357 | Critical | Verify packages exist before import | +| XSS (Reflected/Stored/DOM) | CWE-79 | Critical | Encode output for context | +| Hardcoded Secrets | CWE-798 | Critical | Use environment variables | +| SQL Injection | CWE-89 | Critical | Use parameterized queries | +| Missing Authentication | CWE-287 | Critical | Apply auth to all protected endpoints | +| Command Injection | CWE-78 | Critical | Use argument arrays, avoid shell | +| Missing Input Validation | CWE-20 | High | Validate type, length, format, range | +| Unrestricted File Upload | CWE-434 | Critical | Validate extension, MIME, and size | +| Insufficient Randomness | CWE-330 | High | Use secrets module for tokens | +| Missing Rate Limiting | CWE-770 | High | Implement per-IP/user limits | +| Excessive Data Exposure | CWE-200 | High | Use DTOs with field allowlists | +| Path Traversal | CWE-22 | High | Validate paths within allowed dirs | +| Weak Password Hashing | CWE-327 | High | Use bcrypt/argon2 with salt | +| Log Injection | CWE-117 | Medium | Sanitize newlines, use structured logging | +| Debug Mode in Production | CWE-215 | High | Environment-based configuration | +| Weak Encryption | CWE-326 | High | Use AES-GCM or ChaCha20-Poly1305 | +| Session Fixation | CWE-384 | High | Regenerate session ID on login | +| JWT Misuse | CWE-287 | High | Strong secrets, explicit algorithms | +| Mass Assignment | CWE-915 | High | Allowlist assignable fields | +| Missing Security Headers | CWE-16 | Medium | Add CSP, X-Frame-Options, HSTS | +| Open CORS | CWE-346 | Medium | Restrict to known origins | +| LDAP Injection | CWE-90 | High | Escape special LDAP characters | +| XPath Injection | CWE-643 | High | Use parameterized XPath or validate | +| Insecure Temp Files | CWE-377 | Medium | Use mkstemp with restrictive perms | +| Verbose Error Messages | CWE-209 | Medium | Generic external, detailed internal | + +--- + +## 1. Secrets and Credentials Management + +**CWE References:** CWE-798 (Hard-coded Credentials), CWE-259 (Hard-coded Password) +**Severity:** Critical | **Related:** [[Hardcoded-Secrets]] + +> **Risk:** Secrets committed to version control are scraped within minutes. Leads to cloud resource abuse, data breaches, and significant financial costs. AI frequently generates code with embedded credentials from tutorial examples. + +### 1.1 Hardcoded Passwords and API Keys + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Hardcoded API keys and passwords +// ======================================== +CONSTANT API_KEY = "sk-abcd1234efgh5678ijkl9012mnop3456" +CONSTANT DB_PASSWORD = "super_secret_password" +CONSTANT AWS_ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE" +CONSTANT AWS_SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" + +FUNCTION call_api(endpoint): + headers = {"Authorization": "Bearer " + API_KEY} + RETURN http.get(endpoint, headers) +END FUNCTION + +// ======================================== +// GOOD: Environment variables +// ======================================== +FUNCTION call_api(endpoint): + api_key = environment.get("API_KEY") + + IF api_key IS NULL: + THROW Error("API_KEY environment variable required") + END IF + + headers = {"Authorization": "Bearer " + api_key} + RETURN http.get(endpoint, headers) +END FUNCTION +``` + +### 1.2 Credentials in Configuration Files + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Credentials in config committed to repo +// ======================================== +// config.json (tracked in git) +{ + "database_url": "postgresql://admin:password123@localhost:5432/mydb", + "redis_password": "redis_secret_123", + "smtp_password": "mail_password" +} + +FUNCTION connect_database(): + config = load_json("config.json") + connection = database.connect(config.database_url) + RETURN connection +END FUNCTION + +// ======================================== +// GOOD: External secret management +// ======================================== +// config.json (no secrets, safe to commit) +{ + "database_host": "localhost", + "database_port": 5432, + "database_name": "mydb" +} + +FUNCTION connect_database(): + config = load_json("config.json") + + // Credentials from environment or secret manager + db_user = environment.get("DB_USER") + db_password = environment.get("DB_PASSWORD") + + IF db_user IS NULL OR db_password IS NULL: + THROW Error("Database credentials not configured") + END IF + + url = "postgresql://" + db_user + ":" + db_password + "@" + + config.database_host + ":" + config.database_port + "/" + config.database_name + RETURN database.connect(url) +END FUNCTION +``` + +### 1.3 Secrets in Client-Side Code + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Secrets exposed in frontend JavaScript +// ======================================== +// frontend.js (served to browser) +CONSTANT STRIPE_SECRET_KEY = "sk_live_abc123..." // Never expose secret keys! +CONSTANT ADMIN_PASSWORD = "admin123" + +FUNCTION charge_card(card_number, amount): + RETURN http.post("https://api.stripe.com/charges", { + api_key: STRIPE_SECRET_KEY, // Visible in browser DevTools! + card: card_number, + amount: amount + }) +END FUNCTION + +// ======================================== +// GOOD: Backend proxy for sensitive operations +// ======================================== +// frontend.js +FUNCTION charge_card(card_token, amount): + // Only send public token, backend handles secret key + RETURN http.post("/api/charges", { + token: card_token, + amount: amount + }) +END FUNCTION + +// backend.js (server-side only) +FUNCTION handle_charge(request): + stripe_key = environment.get("STRIPE_SECRET_KEY") + + RETURN stripe.charges.create({ + api_key: stripe_key, + source: request.token, + amount: request.amount + }) +END FUNCTION +``` + +### 1.4 Insecure Credential Storage + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Storing credentials in plaintext +// ======================================== +FUNCTION save_user_credentials(username, password): + // Dangerous: Plaintext password storage + database.insert("credentials", { + username: username, + password: password // Stored as-is! + }) +END FUNCTION + +FUNCTION save_api_key(user_id, api_key): + // Dangerous: No encryption + database.insert("api_keys", { + user_id: user_id, + key: api_key + }) +END FUNCTION + +// ======================================== +// GOOD: Proper credential protection +// ======================================== +FUNCTION save_user_credentials(username, password): + // Hash passwords with bcrypt + salt = bcrypt.generate_salt(rounds=12) + password_hash = bcrypt.hash(password, salt) + + database.insert("credentials", { + username: username, + password_hash: password_hash + }) +END FUNCTION + +FUNCTION save_api_key(user_id, api_key): + // Encrypt sensitive data at rest + encryption_key = secret_manager.get("DATA_ENCRYPTION_KEY") + encrypted_key = aes_gcm_encrypt(api_key, encryption_key) + + database.insert("api_keys", { + user_id: user_id, + encrypted_key: encrypted_key + }) +END FUNCTION +``` + +### 1.5 Missing Secret Rotation Considerations + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Static secrets with no rotation capability +// ======================================== +CONSTANT JWT_SECRET = "static_jwt_secret_forever" + +FUNCTION create_token(user_id): + // No way to rotate without breaking all existing tokens + RETURN jwt.encode({user: user_id}, JWT_SECRET, algorithm="HS256") +END FUNCTION + +// ======================================== +// GOOD: Versioned secrets supporting rotation +// ======================================== +FUNCTION get_jwt_secret(version=NULL): + IF version IS NULL: + version = environment.get("JWT_SECRET_VERSION", "v1") + END IF + + // Fetch versioned secret from manager + RETURN secret_manager.get("JWT_SECRET_" + version) +END FUNCTION + +FUNCTION create_token(user_id): + current_version = environment.get("JWT_SECRET_VERSION") + secret = get_jwt_secret(current_version) + + payload = { + user: user_id, + secret_version: current_version, // Include version for validation + exp: current_timestamp() + 3600 + } + RETURN jwt.encode(payload, secret, algorithm="HS256") +END FUNCTION + +FUNCTION verify_token(token): + // Decode header to get version + unverified = jwt.decode(token, verify=FALSE) + version = unverified.get("secret_version", "v1") + + secret = get_jwt_secret(version) + RETURN jwt.decode(token, secret, algorithms=["HS256"]) +END FUNCTION +``` + +--- + +## 2. Injection Vulnerabilities + +**CWE References:** CWE-89 (SQL Injection), CWE-78 (OS Command Injection), CWE-90 (LDAP Injection), CWE-643 (XPath Injection), CWE-943 (NoSQL Injection), CWE-1336 (Template Injection) +**Severity:** Critical | **Related:** [[Injection-Vulnerabilities]] + +> **Risk:** Injection vulnerabilities allow attackers to execute arbitrary code, queries, or commands by manipulating user input. AI models frequently generate vulnerable string concatenation patterns from training data containing millions of insecure examples. Always use parameterized queries and avoid dynamic command construction. + +### 2.1 SQL Injection (String Concatenation in Queries) + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: String concatenation in SQL queries +// ======================================== +FUNCTION get_user(username): + // Vulnerable: User input directly concatenated + query = "SELECT * FROM users WHERE username = '" + username + "'" + RETURN database.execute(query) +END FUNCTION + +FUNCTION search_products(category, min_price): + // Vulnerable: Multiple injection points + query = "SELECT * FROM products WHERE category = '" + category + + "' AND price > " + min_price + RETURN database.execute(query) +END FUNCTION + +// Attack: username = "admin' OR '1'='1' --" +// Result: SELECT * FROM users WHERE username = 'admin' OR '1'='1' --' +// This bypasses authentication and returns all users + +// ======================================== +// GOOD: Parameterized queries (prepared statements) +// ======================================== +FUNCTION get_user(username): + // Safe: Parameters are escaped automatically + query = "SELECT * FROM users WHERE username = ?" + RETURN database.execute(query, [username]) +END FUNCTION + +FUNCTION search_products(category, min_price): + // Safe: All parameters bound separately + query = "SELECT * FROM products WHERE category = ? AND price > ?" + RETURN database.execute(query, [category, min_price]) +END FUNCTION + +// With named parameters (preferred for clarity) +FUNCTION get_user_named(username): + query = "SELECT * FROM users WHERE username = :username" + RETURN database.execute(query, {username: username}) +END FUNCTION +``` + +### 2.2 Command Injection (Unsanitized Shell Commands) + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Shell command with user input +// ======================================== +FUNCTION ping_host(hostname): + // Vulnerable: User controls shell command + command = "ping -c 4 " + hostname + RETURN shell.execute(command) +END FUNCTION + +FUNCTION convert_file(input_path, output_format): + // Vulnerable: Multiple injection points + command = "convert " + input_path + " output." + output_format + RETURN shell.execute(command) +END FUNCTION + +// Attack: hostname = "google.com; rm -rf /" +// Result: ping -c 4 google.com; rm -rf / +// This executes the ping AND deletes the filesystem + +// ======================================== +// GOOD: Use argument arrays, avoid shell +// ======================================== +FUNCTION ping_host(hostname): + // Validate input format first + IF NOT is_valid_hostname(hostname): + THROW Error("Invalid hostname format") + END IF + + // Safe: Arguments passed as array, no shell interpolation + RETURN process.execute(["ping", "-c", "4", hostname], shell=FALSE) +END FUNCTION + +FUNCTION convert_file(input_path, output_format): + // Validate allowed formats + allowed_formats = ["png", "jpg", "gif", "webp"] + IF output_format NOT IN allowed_formats: + THROW Error("Invalid output format") + END IF + + // Validate path is within allowed directory + IF NOT path.is_within(input_path, UPLOAD_DIRECTORY): + THROW Error("Invalid file path") + END IF + + output_path = path.join(OUTPUT_DIR, "output." + output_format) + RETURN process.execute(["convert", input_path, output_path], shell=FALSE) +END FUNCTION + +// Helper: Validate hostname format +FUNCTION is_valid_hostname(hostname): + // Only allow alphanumeric, dots, and hyphens + pattern = "^[a-zA-Z0-9][a-zA-Z0-9.-]{0,253}[a-zA-Z0-9]$" + RETURN regex.match(pattern, hostname) +END FUNCTION +``` + +### 2.3 LDAP Injection + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Unescaped LDAP filters +// ======================================== +FUNCTION find_user_by_name(username): + // Vulnerable: User input in LDAP filter + filter = "(uid=" + username + ")" + RETURN ldap.search("ou=users,dc=example,dc=com", filter) +END FUNCTION + +FUNCTION authenticate_ldap(username, password): + // Vulnerable: Both fields injectable + filter = "(&(uid=" + username + ")(userPassword=" + password + "))" + results = ldap.search(BASE_DN, filter) + RETURN results.count > 0 +END FUNCTION + +// Attack: username = "*)(uid=*))(|(uid=*" +// Result: (uid=*)(uid=*))(|(uid=*) +// This can return all users or bypass authentication + +// ======================================== +// GOOD: Escape LDAP special characters +// ======================================== +FUNCTION escape_ldap(input): + // Escape LDAP special characters: * ( ) \ NUL + result = input + result = result.replace("\\", "\\5c") // Backslash first + result = result.replace("*", "\\2a") + result = result.replace("(", "\\28") + result = result.replace(")", "\\29") + result = result.replace("\0", "\\00") + RETURN result +END FUNCTION + +FUNCTION find_user_by_name(username): + // Safe: Input is escaped before use + safe_username = escape_ldap(username) + filter = "(uid=" + safe_username + ")" + RETURN ldap.search("ou=users,dc=example,dc=com", filter) +END FUNCTION + +FUNCTION authenticate_ldap(username, password): + // Better: Use LDAP bind for authentication instead of filter + user_dn = "uid=" + escape_ldap(username) + ",ou=users,dc=example,dc=com" + + TRY: + connection = ldap.bind(user_dn, password) + connection.close() + RETURN TRUE + CATCH LDAPError: + RETURN FALSE + END TRY +END FUNCTION +``` + +### 2.4 XPath Injection + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Unescaped XPath queries +// ======================================== +FUNCTION find_user_xml(username): + // Vulnerable: User input in XPath expression + xpath = "//users/user[name='" + username + "']" + RETURN xml_document.query(xpath) +END FUNCTION + +FUNCTION authenticate_xml(username, password): + // Vulnerable: Both fields injectable + xpath = "//users/user[name='" + username + "' and password='" + password + "']" + result = xml_document.query(xpath) + RETURN result IS NOT EMPTY +END FUNCTION + +// Attack: username = "admin' or '1'='1" +// Result: //users/user[name='admin' or '1'='1'] +// This returns all users, bypassing authentication + +// ======================================== +// GOOD: Parameterized XPath or strict validation +// ======================================== +// Option 1: Use parameterized XPath (if supported) +FUNCTION find_user_xml(username): + xpath = "//users/user[name=$username]" + RETURN xml_document.query(xpath, {username: username}) +END FUNCTION + +// Option 2: Escape XPath special characters +FUNCTION escape_xpath(input): + // Handle quotes by splitting and concatenating + IF input.contains("'") AND input.contains('"'): + // Use concat() for strings with both quote types + parts = input.split("'") + escaped = "concat('" + parts.join("',\"'\",'" ) + "')" + RETURN escaped + ELSE IF input.contains("'"): + RETURN '"' + input + '"' + ELSE: + RETURN "'" + input + "'" + END IF +END FUNCTION + +FUNCTION find_user_xml_escaped(username): + // Validate input format first + IF NOT is_valid_username(username): + THROW Error("Invalid username format") + END IF + + safe_username = escape_xpath(username) + xpath = "//users/user[name=" + safe_username + "]" + RETURN xml_document.query(xpath) +END FUNCTION + +// Option 3: Strict whitelist validation +FUNCTION is_valid_username(username): + // Only allow alphanumeric and limited special chars + pattern = "^[a-zA-Z0-9_.-]{1,64}$" + RETURN regex.match(pattern, username) +END FUNCTION +``` + +### 2.5 NoSQL Injection + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: Unvalidated input in NoSQL queries +// ======================================== +FUNCTION find_user_nosql(query_params): + // Vulnerable: User can inject operators + // If query_params = {"username": {"$ne": ""}} + // This returns all users where username is not empty + RETURN mongodb.collection("users").find(query_params) +END FUNCTION + +FUNCTION authenticate_nosql(username, password): + // Vulnerable: Accepts objects, not just strings + query = { + username: username, // Could be {"$gt": ""} + password: password // Could be {"$gt": ""} + } + user = mongodb.collection("users").find_one(query) + RETURN user IS NOT NULL +END FUNCTION + +// Attack via JSON body: +// {"username": {"$gt": ""}, "password": {"$gt": ""}} +// This bypasses authentication by matching any non-empty values + +// ======================================== +// GOOD: Type validation and operator blocking +// ======================================== +FUNCTION find_user_nosql(username): + // Validate input is a string, not an object + IF typeof(username) != "string": + THROW Error("Username must be a string") + END IF + + // Safe: Only string values can be queried + RETURN mongodb.collection("users").find_one({username: username}) +END FUNCTION + +FUNCTION authenticate_nosql(username, password): + // Strict type checking + IF typeof(username) != "string" OR typeof(password) != "string": + THROW Error("Invalid credential types") + END IF + + // Additional: Block MongoDB operators + IF username.starts_with("$") OR password.starts_with("$"): + THROW Error("Invalid characters in credentials") + END IF + + user = mongodb.collection("users").find_one({username: username}) + + IF user IS NULL: + RETURN FALSE + END IF + + // Compare password hash, not plaintext + RETURN bcrypt.verify(password, user.password_hash) +END FUNCTION + +// Sanitize any object to remove operators +FUNCTION sanitize_query(obj): + IF typeof(obj) != "object": + RETURN obj + END IF + + sanitized = {} + FOR key, value IN obj: + // Block all MongoDB operators + IF key.starts_with("$"): + CONTINUE // Skip operator keys + END IF + + IF typeof(value) == "object": + // Recursively sanitize, but block nested operators + IF has_operator_keys(value): + THROW Error("Query operators not allowed") + END IF + END IF + + sanitized[key] = value + END FOR + RETURN sanitized +END FUNCTION +``` + +### 2.6 Template Injection (SSTI) + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: User input in template strings +// ======================================== +FUNCTION render_greeting(username): + // Vulnerable: User input treated as template code + template_string = "Hello, " + username + "!" + RETURN template_engine.render_string(template_string) +END FUNCTION + +FUNCTION render_email(user_template, user_data): + // Dangerous: User-provided template + RETURN template_engine.render_string(user_template, user_data) +END FUNCTION + +// Attack: username = "{{config.SECRET_KEY}}" +// Result: Template engine evaluates and exposes secret key +// Attack: username = "{{''.__class__.__mro__[1].__subclasses__()}}" +// Result: Can achieve remote code execution in some engines + +// ======================================== +// GOOD: Use templates as data, not code +// ======================================== +FUNCTION render_greeting(username): + // Safe: User input passed as data to pre-defined template + template = template_engine.load("greeting.html") + RETURN template.render({username: escape_html(username)}) +END FUNCTION + +// greeting.html (static, not user-provided): +//
Hello, {{ username }}!
+ +FUNCTION render_email_safe(template_name, user_data): + // Safe: Only allow pre-defined templates + allowed_templates = ["welcome", "reset_password", "notification"] + + IF template_name NOT IN allowed_templates: + THROW Error("Invalid template name") + END IF + + // Sanitize all user data + safe_data = {} + FOR key, value IN user_data: + safe_data[key] = escape_html(string(value)) + END FOR + + template = template_engine.load(template_name + ".html") + RETURN template.render(safe_data) +END FUNCTION + +// For user-customizable content, use a safe subset +FUNCTION render_user_content(content): + // Use a sandboxed/logic-less template engine + // or plain text with variable substitution only + allowed_vars = ["name", "date", "product"] + + result = content + FOR var_name IN allowed_vars: + placeholder = "{{" + var_name + "}}" + IF var_name IN context: + result = result.replace(placeholder, escape_html(context[var_name])) + END IF + END FOR + + // Remove any remaining template syntax + result = regex.replace(result, "\{\{.*?\}\}", "") + + RETURN result +END FUNCTION +``` + +--- + +## 3. Cross-Site Scripting (XSS) + +**CWE References:** CWE-79 (Improper Neutralization of Input During Web Page Generation), CWE-80 (Improper Neutralization of Script-Related HTML Tags) +**Severity:** Critical | **Related:** [[XSS-Vulnerabilities]] + +> **Risk:** XSS has the **highest failure rate (86%)** in AI-generated code. AI models are 2.74x more likely to produce XSS-vulnerable code than human developers. XSS enables session hijacking, account takeover, and data theft. AI frequently generates direct string concatenation into HTML without encoding. + +### 3.1 Reflected XSS (Echoing User Input) + +``` +// PSEUDOCODE - Implement in your target language + +// ======================================== +// BAD: User input directly echoed in response +// ======================================== +FUNCTION handle_search(request): + query = request.get_parameter("q") + + // Vulnerable: User input inserted directly into HTML + html = "No results found.
" + RETURN html_response(html) +END FUNCTION + +FUNCTION display_error(error_message): + // Vulnerable: Error parameter reflected without encoding + RETURN "No results found.
" + RETURN html_response(html) +END FUNCTION + +FUNCTION display_error(error_message): + // Safe: Encode before inserting into HTML + RETURN "" + html_encode(comment.text) + "
" + html += "
" + comment.text + "
" + html += "