create-agentic-app 1.1.56 → 1.1.58
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.
- package/package.json +1 -1
- package/template/.agents/skills/security-scanner/SKILL.md +157 -0
- package/template/.agents/skills/security-scanner/references/A01-broken-access-control.md +136 -0
- package/template/.agents/skills/security-scanner/references/A02-security-misconfiguration.md +130 -0
- package/template/.agents/skills/security-scanner/references/A03-software-supply-chain-failures.md +117 -0
- package/template/.agents/skills/security-scanner/references/A04-cryptographic-failures.md +141 -0
- package/template/.agents/skills/security-scanner/references/A05-injection.md +155 -0
- package/template/.agents/skills/security-scanner/references/A06-insecure-design.md +145 -0
- package/template/.agents/skills/security-scanner/references/A07-authentication-failures.md +150 -0
- package/template/.agents/skills/security-scanner/references/A08-software-data-integrity-failures.md +132 -0
- package/template/.agents/skills/security-scanner/references/A09-security-logging-alerting-failures.md +130 -0
- package/template/.agents/skills/security-scanner/references/A10-mishandling-exceptional-conditions.md +154 -0
- package/template/.agents/skills/security-scanner/references/report-template.md +148 -0
- package/template/.claude/agents/security-scanner.md +214 -0
- package/template/.claude/skills/security-scanner/SKILL.md +157 -0
- package/template/.claude/skills/security-scanner/references/A01-broken-access-control.md +136 -0
- package/template/.claude/skills/security-scanner/references/A02-security-misconfiguration.md +130 -0
- package/template/.claude/skills/security-scanner/references/A03-software-supply-chain-failures.md +117 -0
- package/template/.claude/skills/security-scanner/references/A04-cryptographic-failures.md +141 -0
- package/template/.claude/skills/security-scanner/references/A05-injection.md +155 -0
- package/template/.claude/skills/security-scanner/references/A06-insecure-design.md +145 -0
- package/template/.claude/skills/security-scanner/references/A07-authentication-failures.md +150 -0
- package/template/.claude/skills/security-scanner/references/A08-software-data-integrity-failures.md +132 -0
- package/template/.claude/skills/security-scanner/references/A09-security-logging-alerting-failures.md +130 -0
- package/template/.claude/skills/security-scanner/references/A10-mishandling-exceptional-conditions.md +154 -0
- package/template/.claude/skills/security-scanner/references/report-template.md +148 -0
- package/template/AGENTS.md +21 -77
- package/template/DESIGN.md +451 -0
- package/template/next-env.d.ts +1 -1
- package/template/specs/ui-polish-responsive/README.md +59 -0
- package/template/specs/ui-polish-responsive/action-required.md +3 -0
- package/template/specs/ui-polish-responsive/requirements.md +53 -0
- package/template/specs/ui-polish-responsive/tasks/task-01-globals-css.md +144 -0
- package/template/specs/ui-polish-responsive/tasks/task-02-layout.md +66 -0
- package/template/specs/ui-polish-responsive/tasks/task-03-site-header.md +79 -0
- package/template/specs/ui-polish-responsive/tasks/task-04-site-footer.md +63 -0
- package/template/specs/ui-polish-responsive/tasks/task-05-home-page.md +215 -0
- package/template/specs/ui-polish-responsive/tasks/task-06-dashboard.md +222 -0
- package/template/specs/ui-polish-responsive/tasks/task-07-chat-page.md +225 -0
- package/template/specs/ui-polish-responsive/tasks/task-08-profile-page.md +192 -0
- package/template/specs/ui-polish-responsive/tasks/task-09-auth-pages.md +97 -0
- package/template/specs/ui-polish-responsive/tasks/task-10-setup-checklist.md +120 -0
- package/template/specs/ui-polish-responsive/tasks/task-11-starter-prompt-modal.md +87 -0
- package/template/src/app/globals.css +65 -7
- package/template/src/app/layout.tsx +2 -2
- package/template/src/app/page.tsx +174 -174
- package/template/src/components/setup-checklist.tsx +162 -162
- package/template/src/components/site-footer.tsx +2 -2
- package/template/src/components/site-header.tsx +3 -3
- package/template/src/components/starter-prompt-modal.tsx +202 -202
|
@@ -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
|
package/template/.claude/skills/security-scanner/references/A08-software-data-integrity-failures.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# A08:2025 — Software or Data Integrity Failures
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Software or Data Integrity Failures is #8 in OWASP Top 10:2025. This category covers failures to maintain trust boundaries and verify that software, code, and data are trustworthy before treating them as valid. It encompasses 14 CWEs with 501,327 total occurrences and 3,331 CVEs. Key concerns include insecure deserialization, code execution from untrusted sources, and CI/CD pipeline integrity.
|
|
6
|
+
|
|
7
|
+
## Key CWEs
|
|
8
|
+
|
|
9
|
+
- **CWE-502**: Deserialization of Untrusted Data
|
|
10
|
+
- **CWE-829**: Inclusion of Functionality from Untrusted Control Sphere
|
|
11
|
+
- **CWE-915**: Improperly Controlled Modification of Dynamically-Determined Object Attributes
|
|
12
|
+
- **CWE-494**: Download of Code Without Integrity Check
|
|
13
|
+
- **CWE-345**: Insufficient Verification of Data Authenticity
|
|
14
|
+
- **CWE-353**: Missing Support for Integrity Check
|
|
15
|
+
|
|
16
|
+
## What to Look For
|
|
17
|
+
|
|
18
|
+
### General Patterns
|
|
19
|
+
- Deserialization of untrusted data (user-submitted serialized objects)
|
|
20
|
+
- `eval()` or `Function()` executing user-provided code
|
|
21
|
+
- CDN/external scripts loaded without Subresource Integrity (SRI) hashes
|
|
22
|
+
- Auto-update mechanisms without signature verification
|
|
23
|
+
- CI/CD pipelines without integrity verification steps
|
|
24
|
+
- Unsigned firmware or software packages
|
|
25
|
+
- Object property injection via mass assignment
|
|
26
|
+
- Dynamic code generation from untrusted input
|
|
27
|
+
- Missing digital signatures on critical data exchanges
|
|
28
|
+
|
|
29
|
+
### Grep Patterns
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
# Deserialization
|
|
33
|
+
deserialize|unserialize|pickle\.load|yaml\.load|readObject
|
|
34
|
+
JSON\.parse.*req\.|JSON\.parse.*body|JSON\.parse.*user
|
|
35
|
+
ObjectInputStream|Marshal\.load|php.*unserialize
|
|
36
|
+
fromJson.*untrusted|Gson.*fromJson
|
|
37
|
+
|
|
38
|
+
# Code execution
|
|
39
|
+
eval\(|Function\(|new Function|vm\.runInContext
|
|
40
|
+
exec\(|execSync\(|compile\(
|
|
41
|
+
setTimeout\(.*['"]|setInterval\(.*['"]
|
|
42
|
+
|
|
43
|
+
# CDN without integrity
|
|
44
|
+
<script.*src=.*http|<link.*href=.*http
|
|
45
|
+
integrity=|crossorigin=
|
|
46
|
+
|
|
47
|
+
# Mass assignment / prototype pollution
|
|
48
|
+
Object\.assign\(.*req\.|\.\.\.req\.body|Object\.merge
|
|
49
|
+
__proto__|prototype\[|constructor\[
|
|
50
|
+
|
|
51
|
+
# Auto-update without verification
|
|
52
|
+
update.*download|download.*update|auto.*update
|
|
53
|
+
checksum|signature|verify.*hash|gpg.*verify
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### JavaScript / TypeScript / Node.js
|
|
57
|
+
- `eval(req.body.data)` or `new Function(req.body.code)()` — executes arbitrary user code
|
|
58
|
+
- `JSON.parse()` on untrusted input without schema validation (prototype pollution risk)
|
|
59
|
+
- `Object.assign(target, req.body)` — mass assignment allows property injection
|
|
60
|
+
- External `<script>` or `<link>` tags without `integrity` attribute
|
|
61
|
+
- `__proto__` or `constructor.prototype` manipulation via user input
|
|
62
|
+
|
|
63
|
+
### Python
|
|
64
|
+
- `pickle.load()` or `yaml.load()` (without `Loader=SafeLoader`) on untrusted data
|
|
65
|
+
- `eval()` or `exec()` with user input
|
|
66
|
+
- `marshal.load()` on untrusted data
|
|
67
|
+
|
|
68
|
+
### Java
|
|
69
|
+
- `ObjectInputStream.readObject()` without input validation — Java deserialization attacks
|
|
70
|
+
- `XMLDecoder` with untrusted XML
|
|
71
|
+
- Libraries like Apache Commons Collections with known gadget chains
|
|
72
|
+
|
|
73
|
+
## Prevention Measures
|
|
74
|
+
|
|
75
|
+
1. Use digital signatures to verify software and data source authenticity
|
|
76
|
+
2. Restrict library/dependency consumption to trusted, vetted repositories
|
|
77
|
+
3. Use tools like OWASP Dependency Check to verify components are free of known vulnerabilities
|
|
78
|
+
4. Enforce code review processes to minimize malicious code introduction
|
|
79
|
+
5. Ensure CI/CD pipeline has proper segregation, configuration, and access controls
|
|
80
|
+
6. Never deserialize untrusted data — or use serialization formats that don't allow code execution (JSON instead of Java serialization, `yaml.safe_load` instead of `yaml.load`)
|
|
81
|
+
7. Add Subresource Integrity (SRI) to all externally loaded scripts/styles
|
|
82
|
+
8. Validate and sanitize all input before processing
|
|
83
|
+
|
|
84
|
+
## Example Attack Scenarios
|
|
85
|
+
|
|
86
|
+
**Scenario 1:** External service provider gains access to authentication cookies through DNS mapping, enabling session hijacking.
|
|
87
|
+
|
|
88
|
+
**Scenario 2:** Unsigned firmware update on router/device used as attack vector with no remediation path.
|
|
89
|
+
|
|
90
|
+
**Scenario 3:** Developers install packages from untrusted sources lacking signature verification, introducing malware.
|
|
91
|
+
|
|
92
|
+
**Scenario 4:** Java deserialization attack — attacker crafts malicious serialized object that executes arbitrary code upon deserialization.
|
|
93
|
+
|
|
94
|
+
## Fix Examples
|
|
95
|
+
|
|
96
|
+
**Before (eval with user input):**
|
|
97
|
+
```typescript
|
|
98
|
+
export async function POST(req) {
|
|
99
|
+
const { data } = await req.json();
|
|
100
|
+
const result = eval(data); // Arbitrary code execution
|
|
101
|
+
return Response.json({ result });
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**After (safe data processing):**
|
|
106
|
+
```typescript
|
|
107
|
+
export async function POST(req) {
|
|
108
|
+
const { data } = await req.json();
|
|
109
|
+
const parsed = JSON.parse(data); // Parse as data only, never as code
|
|
110
|
+
const validated = schema.parse(parsed); // Validate against schema
|
|
111
|
+
return Response.json({ result: processData(validated) });
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Before (Python pickle deserialization):**
|
|
116
|
+
```python
|
|
117
|
+
import pickle
|
|
118
|
+
data = pickle.loads(request.data) # Arbitrary code execution
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**After (safe deserialization):**
|
|
122
|
+
```python
|
|
123
|
+
import json
|
|
124
|
+
data = json.loads(request.data) # JSON cannot execute code
|
|
125
|
+
validated = DataSchema(**data) # Validate against schema
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## References
|
|
129
|
+
|
|
130
|
+
- [OWASP A08:2025](https://owasp.org/Top10/2025/A08_2025-Software_or_Data_Integrity_Failures/)
|
|
131
|
+
- OWASP Cheat Sheet: Deserialization
|
|
132
|
+
- OWASP ASVS: Data Integrity
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# A09:2025 — Security Logging and Alerting Failures
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Security Logging and Alerting Failures is #9 in OWASP Top 10:2025. This category covers insufficient logging, monitoring, and alerting that prevent detection of security breaches. It maps to 5 CWEs with 723 CVEs. Real-world impact is severe: a healthcare provider went 7 years undetected after a breach affecting 3.5M records; a major airline suffered a decade-long data breach at a third-party provider.
|
|
6
|
+
|
|
7
|
+
## Key CWEs
|
|
8
|
+
|
|
9
|
+
- **CWE-117**: Improper Output Neutralization for Logs
|
|
10
|
+
- **CWE-221**: Information Loss or Omission
|
|
11
|
+
- **CWE-223**: Omission of Security-relevant Information
|
|
12
|
+
- **CWE-532**: Insertion of Sensitive Information into Log File
|
|
13
|
+
- **CWE-778**: Insufficient Logging
|
|
14
|
+
|
|
15
|
+
## What to Look For
|
|
16
|
+
|
|
17
|
+
### General Patterns
|
|
18
|
+
- Sensitive data written to logs (passwords, tokens, credit cards, PII, session IDs)
|
|
19
|
+
- Missing audit logging for security-relevant events (login, failed auth, privilege changes, data access)
|
|
20
|
+
- No logging on authentication failures or access control failures
|
|
21
|
+
- Error messages that expose sensitive information to end users
|
|
22
|
+
- Logs without timestamps, request IDs, or sufficient context for forensics
|
|
23
|
+
- Log files stored without integrity protection (can be tampered with)
|
|
24
|
+
- No centralized log aggregation or monitoring
|
|
25
|
+
- Missing alerting on suspicious patterns (brute force, unusual access)
|
|
26
|
+
- Unencoded log entries vulnerable to log injection attacks
|
|
27
|
+
- Logging only to console/stdout without persistence
|
|
28
|
+
|
|
29
|
+
### Grep Patterns
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
# Sensitive data in logs
|
|
33
|
+
console\.log.*password|console\.log.*token|console\.log.*secret
|
|
34
|
+
console\.log.*session|console\.log.*cookie|console\.log.*key
|
|
35
|
+
logger\.info.*password|logger\.debug.*token|log\.info.*credential
|
|
36
|
+
print\(.*password|print\(.*token|logging\.info.*password
|
|
37
|
+
|
|
38
|
+
# Missing security event logging
|
|
39
|
+
login.*fail|auth.*fail|access.*denied|unauthorized
|
|
40
|
+
audit|auditLog|audit_log|security_log|securityEvent
|
|
41
|
+
|
|
42
|
+
# Log injection risk
|
|
43
|
+
console\.log\(.*req\.|logger\.info\(.*req\.body|log\(.*user_input
|
|
44
|
+
|
|
45
|
+
# Logging framework usage
|
|
46
|
+
winston|bunyan|pino|morgan|log4js|logging|logger
|
|
47
|
+
console\.log|console\.error|console\.warn
|
|
48
|
+
|
|
49
|
+
# Error exposure to users
|
|
50
|
+
res\.json.*err|response.*error.*message|render.*error.*stack
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### JavaScript / TypeScript / Node.js
|
|
54
|
+
- `console.log('Login attempt:', email, password)` — passwords in logs
|
|
55
|
+
- `console.log('Session created:', sessionToken)` — tokens in logs
|
|
56
|
+
- Using only `console.log` without a logging framework (no levels, no persistence, no structure)
|
|
57
|
+
- Missing logging on failed authentication, failed authorization, and input validation failures
|
|
58
|
+
- Error responses including `err.message` or `err.stack` sent to client
|
|
59
|
+
|
|
60
|
+
### Python (Django/Flask)
|
|
61
|
+
- `print(f"User {email} login with password {password}")` — passwords in logs
|
|
62
|
+
- Missing `LOGGING` configuration in Django settings
|
|
63
|
+
- No audit trail for admin actions
|
|
64
|
+
- `logging.debug()` containing sensitive request data
|
|
65
|
+
|
|
66
|
+
### Java (Spring)
|
|
67
|
+
- `logger.info("Auth token: " + token)` — tokens in logs
|
|
68
|
+
- Missing Spring Security audit events configuration
|
|
69
|
+
- No `@EventListener` for `AuthenticationFailureBadCredentialsEvent`
|
|
70
|
+
|
|
71
|
+
## Prevention Measures
|
|
72
|
+
|
|
73
|
+
1. Log all authentication events (success and failure) with sufficient context for forensic analysis
|
|
74
|
+
2. Log all access control failures and input validation failures
|
|
75
|
+
3. Use structured, machine-readable log formats compatible with log management tools
|
|
76
|
+
4. Encode log data properly to prevent log injection attacks
|
|
77
|
+
5. Use append-only audit trails with integrity controls for critical events
|
|
78
|
+
6. Never log sensitive data: passwords, tokens, credit card numbers, PII
|
|
79
|
+
7. Establish monitoring and alerting for suspicious patterns (brute force, mass data access)
|
|
80
|
+
8. Implement error-triggered transaction rollbacks where appropriate
|
|
81
|
+
9. Use centralized log aggregation (ELK stack, Splunk, Datadog, etc.)
|
|
82
|
+
10. Create incident response playbooks tied to alerting thresholds
|
|
83
|
+
11. Ensure logs include timestamps, user IDs, IP addresses, and request context
|
|
84
|
+
|
|
85
|
+
## Example Attack Scenarios
|
|
86
|
+
|
|
87
|
+
**Scenario 1:** Healthcare provider breached for 7 years undetected due to absent monitoring — 3.5M children's health records compromised.
|
|
88
|
+
|
|
89
|
+
**Scenario 2:** Major airline suffered a decade-long data breach at third-party cloud provider, discovered only through external investigation.
|
|
90
|
+
|
|
91
|
+
**Scenario 3:** European airline fined EUR 20M under GDPR after payment system breach exposed 400,000+ customer records — insufficient logging delayed detection.
|
|
92
|
+
|
|
93
|
+
## Fix Examples
|
|
94
|
+
|
|
95
|
+
**Before (sensitive data in logs):**
|
|
96
|
+
```typescript
|
|
97
|
+
console.log(`Login attempt: ${email} / ${password}`);
|
|
98
|
+
// ...
|
|
99
|
+
console.log(`Session created: ${sessionToken}`);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**After (safe logging):**
|
|
103
|
+
```typescript
|
|
104
|
+
import { logger } from './logger';
|
|
105
|
+
logger.info('Login attempt', { email, ip: req.ip, timestamp: new Date().toISOString() });
|
|
106
|
+
// ...
|
|
107
|
+
logger.info('Session created', { userId: user.id, ip: req.ip });
|
|
108
|
+
// Never log passwords, tokens, or session IDs
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Before (no security event logging):**
|
|
112
|
+
```typescript
|
|
113
|
+
if (!user) return Response.json({ error: 'Invalid credentials' }, { status: 401 });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**After (with audit logging):**
|
|
117
|
+
```typescript
|
|
118
|
+
if (!user) {
|
|
119
|
+
logger.warn('Failed login attempt', { email, ip: req.ip, reason: 'user_not_found' });
|
|
120
|
+
return Response.json({ error: 'Invalid credentials' }, { status: 401 });
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## References
|
|
125
|
+
|
|
126
|
+
- [OWASP A09:2025](https://owasp.org/Top10/2025/A09_2025-Security_Logging_and_Alerting_Failures/)
|
|
127
|
+
- OWASP Proactive Controls: C9 Security Logging and Monitoring
|
|
128
|
+
- OWASP Cheat Sheet: Application Logging Vocabulary
|
|
129
|
+
- OWASP ASVS V16 Security Logging and Error Handling
|
|
130
|
+
- NIST SP 800-61r2: Computer Security Incident Handling Guide
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# A10:2025 — Mishandling of Exceptional Conditions
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Mishandling of Exceptional Conditions is #10 in OWASP Top 10:2025 — a newly introduced category. It covers 24 CWEs with 769,581 total occurrences and 3,416 CVEs. This category addresses deficiencies in error management: programs that fail to prevent, detect, or respond to unusual and unpredictable situations. These failures threaten confidentiality (info disclosure), availability (denial of service), and integrity (data corruption).
|
|
6
|
+
|
|
7
|
+
## Key CWEs
|
|
8
|
+
|
|
9
|
+
- **CWE-209**: Generation of Error Message Containing Sensitive Information
|
|
10
|
+
- **CWE-234**: Failure to Handle Missing Parameter
|
|
11
|
+
- **CWE-274**: Improper Handling of Insufficient Privileges
|
|
12
|
+
- **CWE-280**: Improper Handling of Insufficient Permissions
|
|
13
|
+
- **CWE-476**: NULL Pointer Dereference
|
|
14
|
+
- **CWE-636**: Not Failing Securely (Fail-Open)
|
|
15
|
+
- **CWE-252**: Unchecked Return Value
|
|
16
|
+
- **CWE-754**: Improper Check for Unusual or Exceptional Conditions
|
|
17
|
+
- **CWE-755**: Improper Handling of Exceptional Conditions
|
|
18
|
+
|
|
19
|
+
## What to Look For
|
|
20
|
+
|
|
21
|
+
### General Patterns
|
|
22
|
+
- Empty catch blocks that swallow errors silently
|
|
23
|
+
- Generic error handling that hides root causes
|
|
24
|
+
- Missing error handling on async operations (unhandled promise rejections)
|
|
25
|
+
- Error responses that expose stack traces, SQL queries, or internal paths to users
|
|
26
|
+
- Fail-open patterns: errors cause the system to grant access instead of denying it
|
|
27
|
+
- Unchecked return values from security-critical functions
|
|
28
|
+
- Missing error handling on file I/O, network calls, database operations
|
|
29
|
+
- Partial transaction failures without rollback
|
|
30
|
+
- Resource leaks when exceptions occur (file handles, DB connections, memory)
|
|
31
|
+
- Missing global/unhandled exception handlers
|
|
32
|
+
- Inconsistent error handling across the application
|
|
33
|
+
|
|
34
|
+
### Grep Patterns
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
# Empty catch blocks
|
|
38
|
+
catch\s*\([^)]*\)\s*\{\s*\}|catch\s*\(\s*\)\s*:|except\s*:.*pass
|
|
39
|
+
catch.*\{\s*\/\/|catch.*\{\s*\n\s*\}
|
|
40
|
+
|
|
41
|
+
# Stack trace / internal info exposure
|
|
42
|
+
err\.stack|error\.stack|e\.getStackTrace|traceback
|
|
43
|
+
err\.message|error\.message|e\.getMessage
|
|
44
|
+
res\.json.*err|response.*stack|render.*error
|
|
45
|
+
|
|
46
|
+
# Fail-open patterns
|
|
47
|
+
catch.*return true|catch.*allow|catch.*grant|catch.*next\(\)
|
|
48
|
+
catch.*continue|on_error.*pass|rescue.*true
|
|
49
|
+
|
|
50
|
+
# Unhandled async
|
|
51
|
+
\.then\((?!.*\.catch)|async.*(?!try)
|
|
52
|
+
unhandledRejection|uncaughtException
|
|
53
|
+
|
|
54
|
+
# Unchecked returns
|
|
55
|
+
=\s*(await\s+)?.*\(.*\)\s*;?\s*$(?!.*if|.*\?|.*throw|.*return)
|
|
56
|
+
|
|
57
|
+
# Resource cleanup
|
|
58
|
+
finally|dispose|close|cleanup|release
|
|
59
|
+
try.*open|try.*connect|try.*acquire
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### JavaScript / TypeScript / Node.js
|
|
63
|
+
- `catch (e) {}` — empty catch block, error silently swallowed
|
|
64
|
+
- `catch (e) { return res.json({ error: e.message, stack: e.stack }) }` — info disclosure
|
|
65
|
+
- Missing `.catch()` on Promises or missing try/catch around `await`
|
|
66
|
+
- Express error middleware missing or exposing internals
|
|
67
|
+
- `process.on('uncaughtException')` handler missing
|
|
68
|
+
- Database/file operations without try/catch in async handlers
|
|
69
|
+
|
|
70
|
+
### Python (Django/Flask)
|
|
71
|
+
- `except: pass` or `except Exception: pass` — swallowing all errors
|
|
72
|
+
- `traceback.format_exc()` returned in HTTP response
|
|
73
|
+
- Missing `finally` blocks for resource cleanup
|
|
74
|
+
- Django `DEBUG = True` in production exposing full tracebacks
|
|
75
|
+
|
|
76
|
+
### Java (Spring)
|
|
77
|
+
- Empty catch blocks: `catch (Exception e) {}`
|
|
78
|
+
- `e.printStackTrace()` in production code
|
|
79
|
+
- Missing `@ControllerAdvice` global exception handler
|
|
80
|
+
- `@ExceptionHandler` returning `e.getMessage()` to client
|
|
81
|
+
|
|
82
|
+
## Prevention Measures
|
|
83
|
+
|
|
84
|
+
1. Catch and handle errors at their point of origin with meaningful responses
|
|
85
|
+
2. Provide user-friendly error messages — never expose internal details
|
|
86
|
+
3. Log all errors with sufficient context for debugging
|
|
87
|
+
4. Use global exception handlers as a safety net for unhandled errors
|
|
88
|
+
5. Roll back transactions completely on failure — no partial state
|
|
89
|
+
6. Apply rate limiting and resource quotas to prevent resource exhaustion
|
|
90
|
+
7. Implement proper resource cleanup in `finally` blocks
|
|
91
|
+
8. Default to deny (fail-closed) — never grant access on error
|
|
92
|
+
9. Conduct stress testing and penetration testing to find edge cases
|
|
93
|
+
10. Aggregate repeated identical errors as statistics to prevent log flooding
|
|
94
|
+
|
|
95
|
+
## Example Attack Scenarios
|
|
96
|
+
|
|
97
|
+
**Scenario 1 — Denial of Service:** File upload exception leaves resources unreleased. Repeated uploads exhaust system resources, causing downtime until restart.
|
|
98
|
+
|
|
99
|
+
**Scenario 2 — Information Disclosure:** Database error message exposes table names, column names, and query structure. Attacker uses this to craft targeted SQL injection attacks.
|
|
100
|
+
|
|
101
|
+
**Scenario 3 — Financial Transaction Compromise:** Network interruption during multi-step transfer. Missing rollback allows attacker to drain accounts or create duplicate transfers.
|
|
102
|
+
|
|
103
|
+
## Fix Examples
|
|
104
|
+
|
|
105
|
+
**Before (empty catch + info disclosure):**
|
|
106
|
+
```typescript
|
|
107
|
+
try {
|
|
108
|
+
const results = db.all(query);
|
|
109
|
+
return Response.json(results);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return Response.json({ error: e.message, sql: query, stack: e.stack });
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**After (proper error handling):**
|
|
116
|
+
```typescript
|
|
117
|
+
try {
|
|
118
|
+
const results = db.all(query);
|
|
119
|
+
return Response.json(results);
|
|
120
|
+
} catch (e) {
|
|
121
|
+
logger.error('Database query failed', { error: e.message, query, stack: e.stack });
|
|
122
|
+
return Response.json({ error: 'An internal error occurred' }, { status: 500 });
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Before (fail-open):**
|
|
127
|
+
```typescript
|
|
128
|
+
try {
|
|
129
|
+
const isAuthorized = await checkPermission(user, resource);
|
|
130
|
+
if (!isAuthorized) return deny();
|
|
131
|
+
} catch (e) {
|
|
132
|
+
// Auth service is down, let them through
|
|
133
|
+
}
|
|
134
|
+
return allow();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**After (fail-closed):**
|
|
138
|
+
```typescript
|
|
139
|
+
try {
|
|
140
|
+
const isAuthorized = await checkPermission(user, resource);
|
|
141
|
+
if (!isAuthorized) return deny();
|
|
142
|
+
return allow();
|
|
143
|
+
} catch (e) {
|
|
144
|
+
logger.error('Authorization check failed', { user: user.id, resource, error: e.message });
|
|
145
|
+
return deny(); // Default to deny on error
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## References
|
|
150
|
+
|
|
151
|
+
- [OWASP A10:2025](https://owasp.org/Top10/2025/A10_2025-Mishandling_of_Exceptional_Conditions/)
|
|
152
|
+
- OWASP Error Handling Cheat Sheet
|
|
153
|
+
- OWASP Logging Cheat Sheet
|
|
154
|
+
- OWASP ASVS V16.5 Error Handling
|