📦 deps(thirdparty): update snapshots
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,167 @@
|
||||
# Security Report Templates
|
||||
|
||||
Templates for documenting security findings and audit reports.
|
||||
|
||||
---
|
||||
|
||||
## Individual Finding Template
|
||||
|
||||
```markdown
|
||||
## {SEVERITY} {VULNERABILITY_NAME}
|
||||
|
||||
**Category**: {OWASP_CATEGORY}
|
||||
**CWE**: {CWE_IDS}
|
||||
**Severity**: Critical/High/Medium/Low
|
||||
|
||||
### Location
|
||||
- File: {FILE_PATH}
|
||||
- Lines: {LINE_RANGE}
|
||||
- Function: {FUNCTION_NAME}
|
||||
|
||||
### Description
|
||||
{CLEAR_EXPLANATION}
|
||||
|
||||
### Impact
|
||||
{WHAT_ATTACKER_COULD_DO}
|
||||
|
||||
### Proof of Concept
|
||||
{CODE_OR_STEPS_TO_EXPLOIT}
|
||||
|
||||
### Remediation
|
||||
{SPECIFIC_FIX_WITH_CODE}
|
||||
|
||||
### References
|
||||
- OWASP: {URL}
|
||||
- CWE: {URL}
|
||||
```
|
||||
|
||||
### Severity Indicators
|
||||
|
||||
Use these indicators in finding titles:
|
||||
|
||||
- **Critical**: Remote code execution, auth bypass, mass data exposure, admin privilege escalation
|
||||
- **High**: SQL injection, stored XSS, auth weaknesses, sensitive data leaks
|
||||
- **Medium**: CSRF, reflected XSS, information disclosure, weak crypto
|
||||
- **Low**: Misconfigurations, missing headers, verbose errors, minor info leaks
|
||||
|
||||
---
|
||||
|
||||
## Audit Report Template
|
||||
|
||||
```markdown
|
||||
# Security Audit Report
|
||||
|
||||
**Date**: {DATE}
|
||||
**Scope**: {COMPONENTS_REVIEWED}
|
||||
**Reviewer**: {NAME}
|
||||
**Version**: {APP_VERSION}
|
||||
|
||||
## Executive Summary
|
||||
|
||||
{1-2 PARAGRAPH HIGH-LEVEL OVERVIEW}
|
||||
|
||||
Overall security posture: {STRONG/ADEQUATE/NEEDS_IMPROVEMENT/CRITICAL}
|
||||
|
||||
## Risk Summary
|
||||
|
||||
| Severity | Count |
|
||||
|----------|-------|
|
||||
| Critical | {N} |
|
||||
| High | {N} |
|
||||
| Medium | {N} |
|
||||
| Low | {N} |
|
||||
|
||||
## Key Findings
|
||||
|
||||
### 1. {MOST_CRITICAL_FINDING}
|
||||
Brief description and impact.
|
||||
|
||||
### 2. {SECOND_FINDING}
|
||||
Brief description and impact.
|
||||
|
||||
### 3. {THIRD_FINDING}
|
||||
Brief description and impact.
|
||||
|
||||
## Detailed Findings
|
||||
|
||||
{FULL_LIST_USING_INDIVIDUAL_FINDING_TEMPLATE}
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Immediate (Critical/High)
|
||||
1. {ACTION_ITEM}
|
||||
2. {ACTION_ITEM}
|
||||
|
||||
### Short-term (Medium)
|
||||
1. {ACTION_ITEM}
|
||||
|
||||
### Long-term (Low / Hardening)
|
||||
1. {ACTION_ITEM}
|
||||
|
||||
## Scope & Methodology
|
||||
|
||||
### In Scope
|
||||
- {COMPONENT_1}
|
||||
- {COMPONENT_2}
|
||||
|
||||
### Out of Scope
|
||||
- {EXCLUDED_ITEM}
|
||||
|
||||
### Methodology
|
||||
- Threat modeling (STRIDE)
|
||||
- Code review
|
||||
- Dependency scanning
|
||||
- {OTHER_METHODS}
|
||||
|
||||
## Conclusion
|
||||
|
||||
{OVERALL_ASSESSMENT_AND_NEXT_STEPS}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Finding Format
|
||||
|
||||
For inline documentation or PR comments:
|
||||
|
||||
```
|
||||
[SEVERITY] VULN_TYPE in FILE:LINE
|
||||
- Issue: {brief description}
|
||||
- Impact: {what attacker could do}
|
||||
- Fix: {one-line remediation}
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
[HIGH] SQL Injection in src/api/users.ts:45
|
||||
- Issue: User email concatenated into query string
|
||||
- Impact: Attacker can extract/modify database
|
||||
- Fix: Use parameterized query with db.execute(sql, [email])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Risk Matrix
|
||||
|
||||
Use for prioritization:
|
||||
|
||||
```
|
||||
IMPACT
|
||||
Low Med High
|
||||
Low Low Low Med
|
||||
LIKELIHOOD Med Low Med High
|
||||
High Med High Crit
|
||||
```
|
||||
|
||||
Factors affecting likelihood:
|
||||
- Skill required to exploit
|
||||
- Access required (unauth vs auth vs admin)
|
||||
- Attack complexity
|
||||
- User interaction needed
|
||||
|
||||
Factors affecting impact:
|
||||
- Confidentiality (data exposure)
|
||||
- Integrity (data modification)
|
||||
- Availability (service disruption)
|
||||
- Scope (single user vs all users vs system)
|
||||
@@ -0,0 +1,124 @@
|
||||
# Security Review Checklist
|
||||
|
||||
Complete checklist for security code review. Check each item before marking review complete.
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
- [ ] Passwords hashed with bcrypt/argon2 (cost >= 12)
|
||||
- [ ] Session tokens cryptographically random (32+ bytes)
|
||||
- [ ] Session cookies: httpOnly, secure, sameSite=strict
|
||||
- [ ] Password reset tokens random + expiring (1 hour max)
|
||||
- [ ] Rate limiting on login (5 attempts / 15 min)
|
||||
- [ ] Account lockout after repeated failures
|
||||
- [ ] MFA available for sensitive accounts
|
||||
- [ ] JWT: signature verified, algorithm specified
|
||||
- [ ] JWT: short expiry, refresh token rotation
|
||||
- [ ] No credentials in URLs or logs
|
||||
|
||||
## Authorization
|
||||
|
||||
- [ ] All endpoints verify authentication server-side
|
||||
- [ ] Resource ownership verified before access (no IDOR)
|
||||
- [ ] Role checks on server, never client-only
|
||||
- [ ] Principle of least privilege applied
|
||||
- [ ] Admin functions require admin role server-side
|
||||
- [ ] API endpoints return 403 for unauthorized, not 404
|
||||
- [ ] Mass assignment prevented (explicit allowlists)
|
||||
- [ ] CORS configured with explicit origins (no wildcards with credentials)
|
||||
|
||||
## Input Validation
|
||||
|
||||
- [ ] All inputs validated (type, length, format)
|
||||
- [ ] SQL queries use parameterized statements
|
||||
- [ ] HTML output escaped or sanitized (no raw innerHTML)
|
||||
- [ ] File uploads validated (type, size, content)
|
||||
- [ ] File names sanitized (path.basename)
|
||||
- [ ] Path traversal prevented (prefix check after join)
|
||||
- [ ] Command injection prevented (execFile, no shell)
|
||||
- [ ] XML parsing disables external entities
|
||||
- [ ] JSON schema validation on API inputs
|
||||
|
||||
## Cryptography
|
||||
|
||||
- [ ] No hardcoded secrets in code
|
||||
- [ ] Secrets from environment variables
|
||||
- [ ] Strong algorithms only (AES-256-GCM, SHA-256+)
|
||||
- [ ] No MD5, SHA1, DES, ECB mode
|
||||
- [ ] crypto.randomBytes for all tokens
|
||||
- [ ] No Math.random for security purposes
|
||||
- [ ] HTTPS enforced (no HTTP endpoints)
|
||||
- [ ] TLS 1.2+ required
|
||||
- [ ] Certificate validation not disabled
|
||||
- [ ] Keys rotated periodically
|
||||
|
||||
## Data Protection
|
||||
|
||||
- [ ] Sensitive data encrypted at rest
|
||||
- [ ] TLS 1.2+ for data in transit
|
||||
- [ ] Sensitive data not logged (passwords, tokens, PII)
|
||||
- [ ] Error messages generic to users, detailed in logs
|
||||
- [ ] PII handling complies with regulations (GDPR, CCPA)
|
||||
- [ ] Database credentials not in code
|
||||
- [ ] Backups encrypted
|
||||
- [ ] Data retention policies implemented
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [ ] All dependencies up to date
|
||||
- [ ] npm audit / cargo audit clean
|
||||
- [ ] No known CVEs in dependencies
|
||||
- [ ] Dependency scanning in CI/CD
|
||||
- [ ] Package lock files committed
|
||||
- [ ] Minimal dependency footprint
|
||||
- [ ] Source verification for dependencies
|
||||
- [ ] No unused dependencies
|
||||
|
||||
## Logging & Monitoring
|
||||
|
||||
- [ ] Authentication events logged (success + failure)
|
||||
- [ ] Authorization failures logged
|
||||
- [ ] Sensitive operations audited (admin actions, data access)
|
||||
- [ ] Log entries include timestamp, user ID, IP, action
|
||||
- [ ] Logs protected from tampering
|
||||
- [ ] No sensitive data in logs
|
||||
- [ ] Log injection prevented (sanitize user input in logs)
|
||||
- [ ] Security events trigger alerts
|
||||
- [ ] Incident response plan documented
|
||||
|
||||
## Infrastructure
|
||||
|
||||
- [ ] Security headers configured (helmet or equivalent)
|
||||
- [ ] Content-Security-Policy
|
||||
- [ ] X-Content-Type-Options: nosniff
|
||||
- [ ] X-Frame-Options: DENY
|
||||
- [ ] Strict-Transport-Security
|
||||
- [ ] Referrer-Policy
|
||||
- [ ] Debug mode disabled in production
|
||||
- [ ] Default accounts/passwords changed
|
||||
- [ ] Unnecessary features/endpoints disabled
|
||||
- [ ] Error pages don't reveal stack traces
|
||||
- [ ] Rate limiting on all public endpoints
|
||||
|
||||
## SSRF Prevention
|
||||
|
||||
- [ ] URL inputs validated against allowlist
|
||||
- [ ] Private IPs blocked (10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x)
|
||||
- [ ] Cloud metadata endpoints blocked (169.254.169.254)
|
||||
- [ ] Redirect following disabled or validated
|
||||
- [ ] DNS rebinding prevented
|
||||
|
||||
---
|
||||
|
||||
## Quick Pre-Commit Checklist
|
||||
|
||||
Minimum checks before any commit touching security-sensitive code:
|
||||
|
||||
1. [ ] No hardcoded secrets
|
||||
2. [ ] Inputs validated
|
||||
3. [ ] SQL parameterized
|
||||
4. [ ] Auth checked server-side
|
||||
5. [ ] Ownership verified for resources
|
||||
6. [ ] Sensitive data not logged
|
||||
7. [ ] npm audit clean
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
# Vulnerability Patterns Reference
|
||||
|
||||
Secure vs vulnerable code patterns organized by category. Each pattern shows the vulnerability and its remediation.
|
||||
|
||||
---
|
||||
|
||||
## Input Validation
|
||||
|
||||
### SQL Injection
|
||||
|
||||
```typescript
|
||||
// VULNERABLE
|
||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`;
|
||||
|
||||
// SECURE - parameterized queries
|
||||
const query = 'SELECT * FROM users WHERE email = ?';
|
||||
db.execute(query, [userEmail]);
|
||||
```
|
||||
|
||||
### XSS (Cross-Site Scripting)
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - direct HTML insertion
|
||||
element.innerHTML = userInput;
|
||||
|
||||
// SECURE - use textContent or sanitize
|
||||
element.textContent = userInput;
|
||||
// OR for rich content
|
||||
element.innerHTML = DOMPurify.sanitize(userInput);
|
||||
```
|
||||
|
||||
### Command Injection
|
||||
|
||||
```typescript
|
||||
// VULNERABLE
|
||||
exec(`convert ${userFilename} output.png`);
|
||||
|
||||
// SECURE - parameterized or allowlist
|
||||
execFile('convert', [userFilename, 'output.png']);
|
||||
```
|
||||
|
||||
### Path Traversal
|
||||
|
||||
```typescript
|
||||
// VULNERABLE
|
||||
const filePath = `/uploads/${userFileName}`;
|
||||
|
||||
// SECURE - validate and normalize
|
||||
const safeName = path.basename(userFileName);
|
||||
const filePath = path.join('/uploads', safeName);
|
||||
if (!filePath.startsWith('/uploads/')) {
|
||||
throw new Error('Invalid path');
|
||||
}
|
||||
```
|
||||
|
||||
### XXE (XML External Entity)
|
||||
|
||||
```typescript
|
||||
// VULNERABLE
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(xmlInput, 'text/xml');
|
||||
|
||||
// SECURE - disable external entities
|
||||
const parser = new DOMParser({
|
||||
locator: {},
|
||||
errorHandler: {},
|
||||
entityResolver: () => null, // Disable DTD processing
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication & Sessions
|
||||
|
||||
### Password Storage
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - plain text or weak hash
|
||||
const hash = md5(password);
|
||||
|
||||
// SECURE - bcrypt/argon2 with salt
|
||||
const hash = await bcrypt.hash(password, 12);
|
||||
```
|
||||
|
||||
### Session Management
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - predictable session IDs
|
||||
const sessionId = userId + Date.now();
|
||||
|
||||
// SECURE - cryptographically random
|
||||
const sessionId = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
// Security attributes
|
||||
res.cookie('session', sessionId, {
|
||||
httpOnly: true,
|
||||
secure: true, // HTTPS only
|
||||
sameSite: 'strict',
|
||||
maxAge: 3600000, // 1 hour
|
||||
});
|
||||
```
|
||||
|
||||
### JWT Handling
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - no signature verification
|
||||
const payload = JSON.parse(atob(token.split('.')[1]));
|
||||
|
||||
// SECURE - verify signature
|
||||
const payload = jwt.verify(token, SECRET_KEY, {
|
||||
algorithms: ['HS256'], // Specify allowed algorithms
|
||||
issuer: 'your-app',
|
||||
audience: 'your-api',
|
||||
});
|
||||
```
|
||||
|
||||
### Password Reset
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - predictable tokens
|
||||
const resetToken = userId + '-' + Date.now();
|
||||
|
||||
// SECURE - cryptographically random with expiry
|
||||
const resetToken = crypto.randomBytes(32).toString('hex');
|
||||
await db.execute(
|
||||
'INSERT INTO reset_tokens (user_id, token, expires_at) VALUES (?, ?, ?)',
|
||||
[userId, await bcrypt.hash(resetToken, 10), Date.now() + 3600000]
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authorization
|
||||
|
||||
### Broken Access Control
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - client-side only check
|
||||
if (user.isAdmin) {
|
||||
// show admin panel
|
||||
}
|
||||
|
||||
// SECURE - server-side enforcement
|
||||
app.get('/admin/users', requireAdmin, (req, res) => {
|
||||
if (!req.user?.isAdmin) {
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
// Admin operation
|
||||
});
|
||||
```
|
||||
|
||||
### IDOR (Insecure Direct Object Reference)
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - no ownership check
|
||||
app.get('/api/documents/:id', async (req, res) => {
|
||||
const doc = await db.getDocument(req.params.id);
|
||||
res.json(doc);
|
||||
});
|
||||
|
||||
// SECURE - verify ownership
|
||||
app.get('/api/documents/:id', async (req, res) => {
|
||||
const doc = await db.getDocument(req.params.id);
|
||||
if (doc.userId !== req.user.id && !req.user.isAdmin) {
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
res.json(doc);
|
||||
});
|
||||
```
|
||||
|
||||
### Privilege Escalation
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - role from client input
|
||||
app.post('/api/users', async (req, res) => {
|
||||
const user = await createUser({
|
||||
...req.body, // Includes role: 'admin' from malicious client
|
||||
});
|
||||
});
|
||||
|
||||
// SECURE - explicit allowlist
|
||||
app.post('/api/users', async (req, res) => {
|
||||
const allowedFields = ['name', 'email', 'password'];
|
||||
const userData = pick(req.body, allowedFields);
|
||||
const user = await createUser({
|
||||
...userData,
|
||||
role: 'user', // Server controls role
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cryptography
|
||||
|
||||
### Weak Algorithms
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - deprecated algorithms
|
||||
const hash = crypto.createHash('md5').update(data).digest('hex');
|
||||
const cipher = crypto.createCipher('des', key);
|
||||
|
||||
// SECURE - modern algorithms
|
||||
const hash = crypto.createHash('sha256').update(data).digest('hex');
|
||||
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
|
||||
```
|
||||
|
||||
### Hardcoded Secrets
|
||||
|
||||
```typescript
|
||||
// VULNERABLE
|
||||
const API_KEY = 'sk-1234567890abcdef';
|
||||
const DB_PASSWORD = 'admin123';
|
||||
|
||||
// SECURE - environment variables
|
||||
const API_KEY = process.env.API_KEY;
|
||||
const DB_PASSWORD = process.env.DB_PASSWORD;
|
||||
|
||||
if (!API_KEY || !DB_PASSWORD) {
|
||||
throw new Error('Missing required environment variables');
|
||||
}
|
||||
```
|
||||
|
||||
### Insufficient Randomness
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - predictable
|
||||
const token = Math.random().toString(36);
|
||||
|
||||
// SECURE - cryptographically secure
|
||||
const token = crypto.randomBytes(32).toString('hex');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Exposure
|
||||
|
||||
### Sensitive Data in Logs
|
||||
|
||||
```typescript
|
||||
// VULNERABLE
|
||||
logger.info('User login', { email, password, ssn });
|
||||
|
||||
// SECURE - redact sensitive fields
|
||||
logger.info('User login', {
|
||||
email,
|
||||
password: '[REDACTED]',
|
||||
ssn: '[REDACTED]',
|
||||
});
|
||||
```
|
||||
|
||||
### Error Message Disclosure
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - exposes internals
|
||||
catch (err) {
|
||||
res.status(500).json({ error: err.stack });
|
||||
}
|
||||
|
||||
// SECURE - generic message
|
||||
catch (err) {
|
||||
logger.error('Internal error', err);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
```
|
||||
|
||||
### Timing Attacks
|
||||
|
||||
```typescript
|
||||
// VULNERABLE - early exit leaks info
|
||||
if (user.password !== inputPassword) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// SECURE - constant-time comparison
|
||||
return crypto.timingSafeEqual(
|
||||
Buffer.from(user.password),
|
||||
Buffer.from(inputPassword)
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Category | Vulnerable Pattern | Secure Pattern |
|
||||
|----------|-------------------|----------------|
|
||||
| SQL Injection | String concatenation | Parameterized queries |
|
||||
| XSS | innerHTML with user input | textContent or DOMPurify |
|
||||
| Command Injection | exec() with user input | execFile() with array args |
|
||||
| Path Traversal | Direct path concat | path.basename + prefix check |
|
||||
| Password Storage | MD5/SHA1/plain | bcrypt (cost 12+) or argon2 |
|
||||
| Session IDs | Predictable (Date.now) | crypto.randomBytes(32) |
|
||||
| JWT | Skip verification | jwt.verify() with algorithm |
|
||||
| Access Control | Client-side only | Server-side on every request |
|
||||
| IDOR | No ownership check | Verify user owns resource |
|
||||
| Secrets | Hardcoded in code | Environment variables |
|
||||
| Error Messages | Stack traces to users | Generic error + log details |
|
||||
Reference in New Issue
Block a user