@jakkrichm/create-nexus-devflow 2.0.12 → 2.0.13
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/lib/update.js +15 -1
- package/package.json +1 -1
- package/template/.agents/skills/70-release/SKILL.md +2 -0
- package/template/.agents/skills/ci/SKILL.md +25 -78
- package/template/.agents/skills/commit/SKILL.md +39 -43
- package/template/.agents/skills/debug/SKILL.md +43 -104
- package/template/.agents/skills/deploy/SKILL.md +37 -65
- package/template/.agents/skills/insight/SKILL.md +27 -116
- package/template/.agents/skills/preview/SKILL.md +24 -103
- package/template/.agents/skills/review/SKILL.md +53 -37
- package/template/.agents/skills/rollback/SKILL.md +1 -0
- package/template/.agents/skills/security-review/SKILL.md +44 -147
- package/template/.agents/skills/simplify/SKILL.md +48 -57
- package/template/.agents/skills/test/SKILL.md +63 -51
- package/template/.claude/skills/70-release/SKILL.md +2 -0
- package/template/.claude/skills/ci/SKILL.md +25 -78
- package/template/.claude/skills/commit/SKILL.md +39 -43
- package/template/.claude/skills/debug/SKILL.md +43 -104
- package/template/.claude/skills/deploy/SKILL.md +37 -65
- package/template/.claude/skills/insight/SKILL.md +27 -116
- package/template/.claude/skills/preview/SKILL.md +24 -103
- package/template/.claude/skills/review/SKILL.md +53 -37
- package/template/.claude/skills/rollback/SKILL.md +1 -0
- package/template/.claude/skills/security-review/SKILL.md +44 -147
- package/template/.claude/skills/simplify/SKILL.md +48 -57
- package/template/.claude/skills/test/SKILL.md +63 -51
- package/template/devflow/history/HISTORY.md +27 -0
- package/template/devflow/reference/running-id-contract.md +1 -1
- package/template/.agents/skills/9arm-skills/README.md +0 -51
- package/template/.agents/skills/9arm-skills/debug-mantra/SKILL.md +0 -86
- package/template/.agents/skills/9arm-skills/management-talk/SKILL.md +0 -79
- package/template/.agents/skills/9arm-skills/post-mortem/SKILL.md +0 -71
- package/template/.agents/skills/9arm-skills/scrutinize/SKILL.md +0 -72
- package/template/.agents/skills/browser-testing-with-devtools/SKILL.md +0 -302
- package/template/.agents/skills/ci-cd-and-automation/SKILL.md +0 -390
- package/template/.agents/skills/code-review-and-quality/SKILL.md +0 -392
- package/template/.agents/skills/code-simplification/SKILL.md +0 -331
- package/template/.agents/skills/debugging-and-error-recovery/SKILL.md +0 -298
- package/template/.agents/skills/deployment-procedures/SKILL.md +0 -241
- package/template/.agents/skills/deprecation-and-migration/SKILL.md +0 -206
- package/template/.agents/skills/diagnosing-bugs/SKILL.md +0 -93
- package/template/.agents/skills/git-workflow-and-versioning/SKILL.md +0 -300
- package/template/.agents/skills/human-review-decisions/SKILL.md +0 -74
- package/template/.agents/skills/idea-refine/SKILL.md +0 -178
- package/template/.agents/skills/idea-refine/examples.md +0 -238
- package/template/.agents/skills/idea-refine/frameworks.md +0 -99
- package/template/.agents/skills/idea-refine/refinement-criteria.md +0 -113
- package/template/.agents/skills/idea-refine/scripts/idea-refine.sh +0 -15
- package/template/.agents/skills/incremental-implementation/SKILL.md +0 -248
- package/template/.agents/skills/insight-capture/SKILL.md +0 -84
- package/template/.agents/skills/intelligent-routing/SKILL.md +0 -176
- package/template/.agents/skills/md2html/SKILL.md +0 -154
- package/template/.agents/skills/md2html/components.md +0 -505
- package/template/.agents/skills/md2html/template.html +0 -1152
- package/template/.agents/skills/planning-and-task-breakdown/SKILL.md +0 -239
- package/template/.agents/skills/pr-review/SKILL.md +0 -143
- package/template/.agents/skills/pr-review-analysis/SKILL.md +0 -89
- package/template/.agents/skills/preview-local-check/SKILL.md +0 -59
- package/template/.agents/skills/release-git-operations/SKILL.md +0 -97
- package/template/.agents/skills/review-followup-routing/SKILL.md +0 -98
- package/template/.agents/skills/security-and-hardening/SKILL.md +0 -349
- package/template/.agents/skills/security-and-hardening/security-checklist.md +0 -134
- package/template/.agents/skills/shipping-and-launch/SKILL.md +0 -311
- package/template/.agents/skills/silent-failure-audit/SKILL.md +0 -73
- package/template/.agents/skills/spec-orchestration/SKILL.md +0 -91
- package/template/.agents/skills/specialist-agent-routing/SKILL.md +0 -107
- package/template/.agents/skills/test-driven-development/SKILL.md +0 -422
- package/template/.agents/skills/test-driven-development/testing-patterns.md +0 -236
- package/template/.agents/skills/test-execution-and-coverage/SKILL.md +0 -56
- package/template/.agents/skills/using-agent-skills/SKILL.md +0 -171
- package/template/.agents/skills/verification-orchestration/SKILL.md +0 -68
- package/template/.agents/skills/vulnerability-scanner/SKILL.md +0 -276
- package/template/.agents/skills/vulnerability-scanner/checklists.md +0 -121
- package/template/.agents/skills/vulnerability-scanner/scripts/security_scan.py +0 -458
- package/template/.agents/skills/wiki/SKILL.md +0 -149
- package/template/.agents/skills/workflow-documentation-sync/SKILL.md +0 -87
- package/template/.claude/skills/9arm-skills/README.md +0 -51
- package/template/.claude/skills/9arm-skills/debug-mantra/SKILL.md +0 -86
- package/template/.claude/skills/9arm-skills/management-talk/SKILL.md +0 -79
- package/template/.claude/skills/9arm-skills/post-mortem/SKILL.md +0 -71
- package/template/.claude/skills/9arm-skills/scrutinize/SKILL.md +0 -72
- package/template/.claude/skills/browser-testing-with-devtools/SKILL.md +0 -302
- package/template/.claude/skills/ci-cd-and-automation/SKILL.md +0 -390
- package/template/.claude/skills/code-review-and-quality/SKILL.md +0 -392
- package/template/.claude/skills/code-simplification/SKILL.md +0 -331
- package/template/.claude/skills/debugging-and-error-recovery/SKILL.md +0 -298
- package/template/.claude/skills/deployment-procedures/SKILL.md +0 -241
- package/template/.claude/skills/deprecation-and-migration/SKILL.md +0 -206
- package/template/.claude/skills/diagnosing-bugs/SKILL.md +0 -93
- package/template/.claude/skills/git-workflow-and-versioning/SKILL.md +0 -300
- package/template/.claude/skills/human-review-decisions/SKILL.md +0 -74
- package/template/.claude/skills/idea-refine/SKILL.md +0 -178
- package/template/.claude/skills/idea-refine/examples.md +0 -238
- package/template/.claude/skills/idea-refine/frameworks.md +0 -99
- package/template/.claude/skills/idea-refine/refinement-criteria.md +0 -113
- package/template/.claude/skills/idea-refine/scripts/idea-refine.sh +0 -15
- package/template/.claude/skills/incremental-implementation/SKILL.md +0 -248
- package/template/.claude/skills/insight-capture/SKILL.md +0 -84
- package/template/.claude/skills/intelligent-routing/SKILL.md +0 -176
- package/template/.claude/skills/md2html/SKILL.md +0 -154
- package/template/.claude/skills/md2html/components.md +0 -505
- package/template/.claude/skills/md2html/template.html +0 -1152
- package/template/.claude/skills/planning-and-task-breakdown/SKILL.md +0 -239
- package/template/.claude/skills/pr-review/SKILL.md +0 -143
- package/template/.claude/skills/pr-review-analysis/SKILL.md +0 -89
- package/template/.claude/skills/preview-local-check/SKILL.md +0 -59
- package/template/.claude/skills/release-git-operations/SKILL.md +0 -97
- package/template/.claude/skills/review-followup-routing/SKILL.md +0 -98
- package/template/.claude/skills/security-and-hardening/SKILL.md +0 -349
- package/template/.claude/skills/security-and-hardening/security-checklist.md +0 -134
- package/template/.claude/skills/shipping-and-launch/SKILL.md +0 -311
- package/template/.claude/skills/silent-failure-audit/SKILL.md +0 -73
- package/template/.claude/skills/spec-orchestration/SKILL.md +0 -91
- package/template/.claude/skills/specialist-agent-routing/SKILL.md +0 -107
- package/template/.claude/skills/test-driven-development/SKILL.md +0 -422
- package/template/.claude/skills/test-driven-development/testing-patterns.md +0 -236
- package/template/.claude/skills/test-execution-and-coverage/SKILL.md +0 -56
- package/template/.claude/skills/using-agent-skills/SKILL.md +0 -171
- package/template/.claude/skills/verification-orchestration/SKILL.md +0 -68
- package/template/.claude/skills/vulnerability-scanner/SKILL.md +0 -276
- package/template/.claude/skills/vulnerability-scanner/checklists.md +0 -121
- package/template/.claude/skills/vulnerability-scanner/scripts/security_scan.py +0 -458
- package/template/.claude/skills/wiki/SKILL.md +0 -149
- package/template/.claude/skills/workflow-documentation-sync/SKILL.md +0 -87
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: review-followup-routing
|
|
3
|
-
description: "[Devflow] Classify review comments, extend existing work safely, and route corrective or future work back into the right DevFlow 2.0 stage. Use for PR follow-up and post-review follow-up planning."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Review Follow-up Routing
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
This skill groups follow-up handling that used to be split across:
|
|
11
|
-
|
|
12
|
-
- `PR-Followup`
|
|
13
|
-
- `Followup`
|
|
14
|
-
|
|
15
|
-
It keeps follow-up work attached to the right running ID without replacing the numbered mainline.
|
|
16
|
-
|
|
17
|
-
## Related Foundation Assets
|
|
18
|
-
|
|
19
|
-
This skill should reuse and align with:
|
|
20
|
-
|
|
21
|
-
- `.agent/resources/schemas/pr_followup.template.md`
|
|
22
|
-
- active stage markdown artifacts under `devflow/runs/{ID}-*/`
|
|
23
|
-
|
|
24
|
-
## Supported Modes
|
|
25
|
-
|
|
26
|
-
- `pr-followup`
|
|
27
|
-
- `task-followup`
|
|
28
|
-
|
|
29
|
-
## When to Use
|
|
30
|
-
|
|
31
|
-
- after `PR-Review` when review comments need classification and response
|
|
32
|
-
- after human feedback, QA, or release review when a task needs additional scoped work
|
|
33
|
-
- when existing work should be extended instead of replaced
|
|
34
|
-
|
|
35
|
-
## Process
|
|
36
|
-
|
|
37
|
-
### 1. Load Current Context
|
|
38
|
-
|
|
39
|
-
Read only the minimum needed:
|
|
40
|
-
|
|
41
|
-
- existing running ID workspace artifacts
|
|
42
|
-
- latest review comments, requested changes, or QA findings
|
|
43
|
-
- current implementation or verification notes when relevant
|
|
44
|
-
|
|
45
|
-
### 2. Classify The Follow-up
|
|
46
|
-
|
|
47
|
-
Classify each item into a useful bucket such as:
|
|
48
|
-
|
|
49
|
-
- fix now
|
|
50
|
-
- already resolved
|
|
51
|
-
- needs clarification
|
|
52
|
-
- new scope follow-up
|
|
53
|
-
- pre-existing issue
|
|
54
|
-
- non-actionable
|
|
55
|
-
|
|
56
|
-
For task follow-up, also classify the change shape:
|
|
57
|
-
|
|
58
|
-
- extension
|
|
59
|
-
- enhancement
|
|
60
|
-
- integration
|
|
61
|
-
- refinement
|
|
62
|
-
- bug fix after review
|
|
63
|
-
|
|
64
|
-
### 3. Preserve Existing History
|
|
65
|
-
|
|
66
|
-
Extend existing markdown artifacts instead of replacing them:
|
|
67
|
-
|
|
68
|
-
- keep current phases and completed work intact
|
|
69
|
-
- append new phases, subtasks, notes, or decision logs
|
|
70
|
-
- keep the same running ID unless the new scope truly deserves a separate work line
|
|
71
|
-
|
|
72
|
-
### 4. Save Reusable Output
|
|
73
|
-
|
|
74
|
-
For PR-centered follow-up, save a report under:
|
|
75
|
-
|
|
76
|
-
```text
|
|
77
|
-
devflow/reports/{date}-pr-followup-{ID}.md
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Use `.agent/resources/schemas/pr_followup.template.md` when a formal report is required.
|
|
81
|
-
|
|
82
|
-
For task follow-up, append the approved follow-up work directly into the relevant stage markdown files for the same running ID.
|
|
83
|
-
|
|
84
|
-
### 5. Route Back
|
|
85
|
-
|
|
86
|
-
- `40-implement` for immediate corrective work
|
|
87
|
-
- `50-verify` when only verification needs another pass
|
|
88
|
-
- `10-define` or `20-spec` when the follow-up becomes genuinely new scope
|
|
89
|
-
|
|
90
|
-
## Output
|
|
91
|
-
|
|
92
|
-
Return:
|
|
93
|
-
|
|
94
|
-
- mode used
|
|
95
|
-
- classification summary
|
|
96
|
-
- what changes now versus later
|
|
97
|
-
- where the follow-up was recorded
|
|
98
|
-
- exact recommended next command
|
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: security-and-hardening
|
|
3
|
-
description: "[Devflow] Hardens code against vulnerabilities. Use when handling user input, authentication, data storage, or external integrations. Use when building any feature that accepts untrusted data, manages user sessions, or interacts with third-party services."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Security and Hardening
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
Security-first development practices for web applications. Treat every external input as hostile, every secret as sacred, and every authorization check as mandatory. Security isn't a phase — it's a constraint on every line of code that touches user data, authentication, or external systems.
|
|
11
|
-
|
|
12
|
-
## When to Use
|
|
13
|
-
|
|
14
|
-
- Building anything that accepts user input
|
|
15
|
-
- Implementing authentication or authorization
|
|
16
|
-
- Storing or transmitting sensitive data
|
|
17
|
-
- Integrating with external APIs or services
|
|
18
|
-
- Adding file uploads, webhooks, or callbacks
|
|
19
|
-
- Handling payment or PII data
|
|
20
|
-
|
|
21
|
-
## The Three-Tier Boundary System
|
|
22
|
-
|
|
23
|
-
### Always Do (No Exceptions)
|
|
24
|
-
|
|
25
|
-
- **Validate all external input** at the system boundary (API routes, form handlers)
|
|
26
|
-
- **Parameterize all database queries** — never concatenate user input into SQL
|
|
27
|
-
- **Encode output** to prevent XSS (use framework auto-escaping, don't bypass it)
|
|
28
|
-
- **Use HTTPS** for all external communication
|
|
29
|
-
- **Hash passwords** with bcrypt/scrypt/argon2 (never store plaintext)
|
|
30
|
-
- **Set security headers** (CSP, HSTS, X-Frame-Options, X-Content-Type-Options)
|
|
31
|
-
- **Use httpOnly, secure, sameSite cookies** for sessions
|
|
32
|
-
- **Run `npm audit`** (or equivalent) before every release
|
|
33
|
-
|
|
34
|
-
### Ask First (Requires Human Approval)
|
|
35
|
-
|
|
36
|
-
- Adding new authentication flows or changing auth logic
|
|
37
|
-
- Storing new categories of sensitive data (PII, payment info)
|
|
38
|
-
- Adding new external service integrations
|
|
39
|
-
- Changing CORS configuration
|
|
40
|
-
- Adding file upload handlers
|
|
41
|
-
- Modifying rate limiting or throttling
|
|
42
|
-
- Granting elevated permissions or roles
|
|
43
|
-
|
|
44
|
-
### Never Do
|
|
45
|
-
|
|
46
|
-
- **Never commit secrets** to version control (API keys, passwords, tokens)
|
|
47
|
-
- **Never log sensitive data** (passwords, tokens, full credit card numbers)
|
|
48
|
-
- **Never trust client-side validation** as a security boundary
|
|
49
|
-
- **Never disable security headers** for convenience
|
|
50
|
-
- **Never use `eval()` or `innerHTML`** with user-provided data
|
|
51
|
-
- **Never store sessions in client-accessible storage** (localStorage for auth tokens)
|
|
52
|
-
- **Never expose stack traces** or internal error details to users
|
|
53
|
-
|
|
54
|
-
## OWASP Top 10 Prevention
|
|
55
|
-
|
|
56
|
-
### 1. Injection (SQL, NoSQL, OS Command)
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
// BAD: SQL injection via string concatenation
|
|
60
|
-
const query = `SELECT * FROM users WHERE id = '${userId}'`;
|
|
61
|
-
|
|
62
|
-
// GOOD: Parameterized query
|
|
63
|
-
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
|
|
64
|
-
|
|
65
|
-
// GOOD: ORM with parameterized input
|
|
66
|
-
const user = await prisma.user.findUnique({ where: { id: userId } });
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### 2. Broken Authentication
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// Password hashing
|
|
73
|
-
import { hash, compare } from 'bcrypt';
|
|
74
|
-
|
|
75
|
-
const SALT_ROUNDS = 12;
|
|
76
|
-
const hashedPassword = await hash(plaintext, SALT_ROUNDS);
|
|
77
|
-
const isValid = await compare(plaintext, hashedPassword);
|
|
78
|
-
|
|
79
|
-
// Session management
|
|
80
|
-
app.use(session({
|
|
81
|
-
secret: process.env.SESSION_SECRET, // From environment, not code
|
|
82
|
-
resave: false,
|
|
83
|
-
saveUninitialized: false,
|
|
84
|
-
cookie: {
|
|
85
|
-
httpOnly: true, // Not accessible via JavaScript
|
|
86
|
-
secure: true, // HTTPS only
|
|
87
|
-
sameSite: 'lax', // CSRF protection
|
|
88
|
-
maxAge: 24 * 60 * 60 * 1000, // 24 hours
|
|
89
|
-
},
|
|
90
|
-
}));
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### 3. Cross-Site Scripting (XSS)
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
// BAD: Rendering user input as HTML
|
|
97
|
-
element.innerHTML = userInput;
|
|
98
|
-
|
|
99
|
-
// GOOD: Use framework auto-escaping (React does this by default)
|
|
100
|
-
return <div>{userInput}</div>;
|
|
101
|
-
|
|
102
|
-
// If you MUST render HTML, sanitize first
|
|
103
|
-
import DOMPurify from 'dompurify';
|
|
104
|
-
const clean = DOMPurify.sanitize(userInput);
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### 4. Broken Access Control
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
// Always check authorization, not just authentication
|
|
111
|
-
app.patch('/api/tasks/:id', authenticate, async (req, res) => {
|
|
112
|
-
const task = await taskService.findById(req.params.id);
|
|
113
|
-
|
|
114
|
-
// Check that the authenticated user owns this resource
|
|
115
|
-
if (task.ownerId !== req.user.id) {
|
|
116
|
-
return res.status(403).json({
|
|
117
|
-
error: { code: 'FORBIDDEN', message: 'Not authorized to modify this task' }
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Proceed with update
|
|
122
|
-
const updated = await taskService.update(req.params.id, req.body);
|
|
123
|
-
return res.json(updated);
|
|
124
|
-
});
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### 5. Security Misconfiguration
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
// Security headers (use helmet for Express)
|
|
131
|
-
import helmet from 'helmet';
|
|
132
|
-
app.use(helmet());
|
|
133
|
-
|
|
134
|
-
// Content Security Policy
|
|
135
|
-
app.use(helmet.contentSecurityPolicy({
|
|
136
|
-
directives: {
|
|
137
|
-
defaultSrc: ["'self'"],
|
|
138
|
-
scriptSrc: ["'self'"],
|
|
139
|
-
styleSrc: ["'self'", "'unsafe-inline'"], // Tighten if possible
|
|
140
|
-
imgSrc: ["'self'", 'data:', 'https:'],
|
|
141
|
-
connectSrc: ["'self'"],
|
|
142
|
-
},
|
|
143
|
-
}));
|
|
144
|
-
|
|
145
|
-
// CORS — restrict to known origins
|
|
146
|
-
app.use(cors({
|
|
147
|
-
origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',
|
|
148
|
-
credentials: true,
|
|
149
|
-
}));
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### 6. Sensitive Data Exposure
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
// Never return sensitive fields in API responses
|
|
156
|
-
function sanitizeUser(user: UserRecord): PublicUser {
|
|
157
|
-
const { passwordHash, resetToken, ...publicFields } = user;
|
|
158
|
-
return publicFields;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Use environment variables for secrets
|
|
162
|
-
const API_KEY = process.env.STRIPE_API_KEY;
|
|
163
|
-
if (!API_KEY) throw new Error('STRIPE_API_KEY not configured');
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## Input Validation Patterns
|
|
167
|
-
|
|
168
|
-
### Schema Validation at Boundaries
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
import { z } from 'zod';
|
|
172
|
-
|
|
173
|
-
const CreateTaskSchema = z.object({
|
|
174
|
-
title: z.string().min(1).max(200).trim(),
|
|
175
|
-
description: z.string().max(2000).optional(),
|
|
176
|
-
priority: z.enum(['low', 'medium', 'high']).default('medium'),
|
|
177
|
-
dueDate: z.string().datetime().optional(),
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
// Validate at the route handler
|
|
181
|
-
app.post('/api/tasks', async (req, res) => {
|
|
182
|
-
const result = CreateTaskSchema.safeParse(req.body);
|
|
183
|
-
if (!result.success) {
|
|
184
|
-
return res.status(422).json({
|
|
185
|
-
error: {
|
|
186
|
-
code: 'VALIDATION_ERROR',
|
|
187
|
-
message: 'Invalid input',
|
|
188
|
-
details: result.error.flatten(),
|
|
189
|
-
},
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
// result.data is now typed and validated
|
|
193
|
-
const task = await taskService.create(result.data);
|
|
194
|
-
return res.status(201).json(task);
|
|
195
|
-
});
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### File Upload Safety
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
// Restrict file types and sizes
|
|
202
|
-
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp'];
|
|
203
|
-
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
|
|
204
|
-
|
|
205
|
-
function validateUpload(file: UploadedFile) {
|
|
206
|
-
if (!ALLOWED_TYPES.includes(file.mimetype)) {
|
|
207
|
-
throw new ValidationError('File type not allowed');
|
|
208
|
-
}
|
|
209
|
-
if (file.size > MAX_SIZE) {
|
|
210
|
-
throw new ValidationError('File too large (max 5MB)');
|
|
211
|
-
}
|
|
212
|
-
// Don't trust the file extension — check magic bytes if critical
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## Triaging npm audit Results
|
|
217
|
-
|
|
218
|
-
Not all audit findings require immediate action. Use this decision tree:
|
|
219
|
-
|
|
220
|
-
```
|
|
221
|
-
npm audit reports a vulnerability
|
|
222
|
-
├── Severity: critical or high
|
|
223
|
-
│ ├── Is the vulnerable code reachable in your app?
|
|
224
|
-
│ │ ├── YES --> Fix immediately (update, patch, or replace the dependency)
|
|
225
|
-
│ │ └── NO (dev-only dep, unused code path) --> Fix soon, but not a blocker
|
|
226
|
-
│ └── Is a fix available?
|
|
227
|
-
│ ├── YES --> Update to the patched version
|
|
228
|
-
│ └── NO --> Check for workarounds, consider replacing the dependency, or add to allowlist with a review date
|
|
229
|
-
├── Severity: moderate
|
|
230
|
-
│ ├── Reachable in production? --> Fix in the next release cycle
|
|
231
|
-
│ └── Dev-only? --> Fix when convenient, track in backlog
|
|
232
|
-
└── Severity: low
|
|
233
|
-
└── Track and fix during regular dependency updates
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Key questions:**
|
|
237
|
-
- Is the vulnerable function actually called in your code path?
|
|
238
|
-
- Is the dependency a runtime dependency or dev-only?
|
|
239
|
-
- Is the vulnerability exploitable given your deployment context (e.g., a server-side vulnerability in a client-only app)?
|
|
240
|
-
|
|
241
|
-
When you defer a fix, document the reason and set a review date.
|
|
242
|
-
|
|
243
|
-
## Rate Limiting
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
import rateLimit from 'express-rate-limit';
|
|
247
|
-
|
|
248
|
-
// General API rate limit
|
|
249
|
-
app.use('/api/', rateLimit({
|
|
250
|
-
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
251
|
-
max: 100, // 100 requests per window
|
|
252
|
-
standardHeaders: true,
|
|
253
|
-
legacyHeaders: false,
|
|
254
|
-
}));
|
|
255
|
-
|
|
256
|
-
// Stricter limit for auth endpoints
|
|
257
|
-
app.use('/api/auth/', rateLimit({
|
|
258
|
-
windowMs: 15 * 60 * 1000,
|
|
259
|
-
max: 10, // 10 attempts per 15 minutes
|
|
260
|
-
}));
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
## Secrets Management
|
|
264
|
-
|
|
265
|
-
```
|
|
266
|
-
.env files:
|
|
267
|
-
├── .env.example → Committed (template with placeholder values)
|
|
268
|
-
├── .env → NOT committed (contains real secrets)
|
|
269
|
-
└── .env.local → NOT committed (local overrides)
|
|
270
|
-
|
|
271
|
-
.gitignore must include:
|
|
272
|
-
.env
|
|
273
|
-
.env.local
|
|
274
|
-
.env.*.local
|
|
275
|
-
*.pem
|
|
276
|
-
*.key
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
**Always check before committing:**
|
|
280
|
-
```bash
|
|
281
|
-
# Check for accidentally staged secrets
|
|
282
|
-
git diff --cached | grep -i "password\|secret\|api_key\|token"
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
## Security Review Checklist
|
|
286
|
-
|
|
287
|
-
```markdown
|
|
288
|
-
### Authentication
|
|
289
|
-
- [ ] Passwords hashed with bcrypt/scrypt/argon2 (salt rounds ≥ 12)
|
|
290
|
-
- [ ] Session tokens are httpOnly, secure, sameSite
|
|
291
|
-
- [ ] Login has rate limiting
|
|
292
|
-
- [ ] Password reset tokens expire
|
|
293
|
-
|
|
294
|
-
### Authorization
|
|
295
|
-
- [ ] Every endpoint checks user permissions
|
|
296
|
-
- [ ] Users can only access their own resources
|
|
297
|
-
- [ ] Admin actions require admin role verification
|
|
298
|
-
|
|
299
|
-
### Input
|
|
300
|
-
- [ ] All user input validated at the boundary
|
|
301
|
-
- [ ] SQL queries are parameterized
|
|
302
|
-
- [ ] HTML output is encoded/escaped
|
|
303
|
-
|
|
304
|
-
### Data
|
|
305
|
-
- [ ] No secrets in code or version control
|
|
306
|
-
- [ ] Sensitive fields excluded from API responses
|
|
307
|
-
- [ ] PII encrypted at rest (if applicable)
|
|
308
|
-
|
|
309
|
-
### Infrastructure
|
|
310
|
-
- [ ] Security headers configured (CSP, HSTS, etc.)
|
|
311
|
-
- [ ] CORS restricted to known origins
|
|
312
|
-
- [ ] Dependencies audited for vulnerabilities
|
|
313
|
-
- [ ] Error messages don't expose internals
|
|
314
|
-
```
|
|
315
|
-
## See Also
|
|
316
|
-
|
|
317
|
-
For detailed security checklists and pre-commit verification steps, see `security-checklist.md`.
|
|
318
|
-
|
|
319
|
-
## Common Rationalizations
|
|
320
|
-
|
|
321
|
-
| Rationalization | Reality |
|
|
322
|
-
|---|---|
|
|
323
|
-
| "This is an internal tool, security doesn't matter" | Internal tools get compromised. Attackers target the weakest link. |
|
|
324
|
-
| "We'll add security later" | Security retrofitting is 10x harder than building it in. Add it now. |
|
|
325
|
-
| "No one would try to exploit this" | Automated scanners will find it. Security by obscurity is not security. |
|
|
326
|
-
| "The framework handles security" | Frameworks provide tools, not guarantees. You still need to use them correctly. |
|
|
327
|
-
| "It's just a prototype" | Prototypes become production. Security habits from day one. |
|
|
328
|
-
|
|
329
|
-
## Red Flags
|
|
330
|
-
|
|
331
|
-
- User input passed directly to database queries, shell commands, or HTML rendering
|
|
332
|
-
- Secrets in source code or commit history
|
|
333
|
-
- API endpoints without authentication or authorization checks
|
|
334
|
-
- Missing CORS configuration or wildcard (`*`) origins
|
|
335
|
-
- No rate limiting on authentication endpoints
|
|
336
|
-
- Stack traces or internal errors exposed to users
|
|
337
|
-
- Dependencies with known critical vulnerabilities
|
|
338
|
-
|
|
339
|
-
## Verification
|
|
340
|
-
|
|
341
|
-
After implementing security-relevant code:
|
|
342
|
-
|
|
343
|
-
- [ ] `npm audit` shows no critical or high vulnerabilities
|
|
344
|
-
- [ ] No secrets in source code or git history
|
|
345
|
-
- [ ] All user input validated at system boundaries
|
|
346
|
-
- [ ] Authentication and authorization checked on every protected endpoint
|
|
347
|
-
- [ ] Security headers present in response (check with browser DevTools)
|
|
348
|
-
- [ ] Error responses don't expose internal details
|
|
349
|
-
- [ ] Rate limiting active on auth endpoints
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
# Security Checklist
|
|
2
|
-
|
|
3
|
-
Quick reference for web application security. Use alongside the `security-and-hardening` skill.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Pre-Commit Checks](#pre-commit-checks)
|
|
8
|
-
- [Authentication](#authentication)
|
|
9
|
-
- [Authorization](#authorization)
|
|
10
|
-
- [Input Validation](#input-validation)
|
|
11
|
-
- [Security Headers](#security-headers)
|
|
12
|
-
- [CORS Configuration](#cors-configuration)
|
|
13
|
-
- [Data Protection](#data-protection)
|
|
14
|
-
- [Dependency Security](#dependency-security)
|
|
15
|
-
- [Error Handling](#error-handling)
|
|
16
|
-
- [OWASP Top 10 Quick Reference](#owasp-top-10-quick-reference)
|
|
17
|
-
|
|
18
|
-
## Pre-Commit Checks
|
|
19
|
-
|
|
20
|
-
- [ ] No secrets in code (`git diff --cached | grep -i "password\|secret\|api_key\|token"`)
|
|
21
|
-
- [ ] `.gitignore` covers: `.env`, `.env.local`, `*.pem`, `*.key`
|
|
22
|
-
- [ ] `.env.example` uses placeholder values (not real secrets)
|
|
23
|
-
|
|
24
|
-
## Authentication
|
|
25
|
-
|
|
26
|
-
- [ ] Passwords hashed with bcrypt (≥12 rounds), scrypt, or argon2
|
|
27
|
-
- [ ] Session cookies: `httpOnly`, `secure`, `sameSite: 'lax'`
|
|
28
|
-
- [ ] Session expiration configured (reasonable max-age)
|
|
29
|
-
- [ ] Rate limiting on login endpoint (≤10 attempts per 15 minutes)
|
|
30
|
-
- [ ] Password reset tokens: time-limited (≤1 hour), single-use
|
|
31
|
-
- [ ] Account lockout after repeated failures (optional, with notification)
|
|
32
|
-
- [ ] MFA supported for sensitive operations (optional but recommended)
|
|
33
|
-
|
|
34
|
-
## Authorization
|
|
35
|
-
|
|
36
|
-
- [ ] Every protected endpoint checks authentication
|
|
37
|
-
- [ ] Every resource access checks ownership/role (prevents IDOR)
|
|
38
|
-
- [ ] Admin endpoints require admin role verification
|
|
39
|
-
- [ ] API keys scoped to minimum necessary permissions
|
|
40
|
-
- [ ] JWT tokens validated (signature, expiration, issuer)
|
|
41
|
-
|
|
42
|
-
## Input Validation
|
|
43
|
-
|
|
44
|
-
- [ ] All user input validated at system boundaries (API routes, form handlers)
|
|
45
|
-
- [ ] Validation uses allowlists (not denylists)
|
|
46
|
-
- [ ] String lengths constrained (min/max)
|
|
47
|
-
- [ ] Numeric ranges validated
|
|
48
|
-
- [ ] Email, URL, and date formats validated with proper libraries
|
|
49
|
-
- [ ] File uploads: type restricted, size limited, content verified
|
|
50
|
-
- [ ] SQL queries parameterized (no string concatenation)
|
|
51
|
-
- [ ] HTML output encoded (use framework auto-escaping)
|
|
52
|
-
- [ ] URLs validated before redirect (prevent open redirect)
|
|
53
|
-
|
|
54
|
-
## Security Headers
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
Content-Security-Policy: default-src 'self'; script-src 'self'
|
|
58
|
-
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
59
|
-
X-Content-Type-Options: nosniff
|
|
60
|
-
X-Frame-Options: DENY
|
|
61
|
-
X-XSS-Protection: 0 (disabled, rely on CSP)
|
|
62
|
-
Referrer-Policy: strict-origin-when-cross-origin
|
|
63
|
-
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## CORS Configuration
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
// Restrictive (recommended)
|
|
70
|
-
cors({
|
|
71
|
-
origin: ['https://yourdomain.com', 'https://app.yourdomain.com'],
|
|
72
|
-
credentials: true,
|
|
73
|
-
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
|
|
74
|
-
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
// NEVER use in production:
|
|
78
|
-
cors({ origin: '*' }) // Allows any origin
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Data Protection
|
|
82
|
-
|
|
83
|
-
- [ ] Sensitive fields excluded from API responses (`passwordHash`, `resetToken`, etc.)
|
|
84
|
-
- [ ] Sensitive data not logged (passwords, tokens, full CC numbers)
|
|
85
|
-
- [ ] PII encrypted at rest (if required by regulation)
|
|
86
|
-
- [ ] HTTPS for all external communication
|
|
87
|
-
- [ ] Database backups encrypted
|
|
88
|
-
|
|
89
|
-
## Dependency Security
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
# Audit dependencies
|
|
93
|
-
npm audit
|
|
94
|
-
|
|
95
|
-
# Fix automatically where possible
|
|
96
|
-
npm audit fix
|
|
97
|
-
|
|
98
|
-
# Check for critical vulnerabilities
|
|
99
|
-
npm audit --audit-level=critical
|
|
100
|
-
|
|
101
|
-
# Keep dependencies updated
|
|
102
|
-
npx npm-check-updates
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Error Handling
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
// Production: generic error, no internals
|
|
109
|
-
res.status(500).json({
|
|
110
|
-
error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' }
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// NEVER in production:
|
|
114
|
-
res.status(500).json({
|
|
115
|
-
error: err.message,
|
|
116
|
-
stack: err.stack, // Exposes internals
|
|
117
|
-
query: err.sql, // Exposes database details
|
|
118
|
-
});
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## OWASP Top 10 Quick Reference
|
|
122
|
-
|
|
123
|
-
| # | Vulnerability | Prevention |
|
|
124
|
-
|---|---|---|
|
|
125
|
-
| 1 | Broken Access Control | Auth checks on every endpoint, ownership verification |
|
|
126
|
-
| 2 | Cryptographic Failures | HTTPS, strong hashing, no secrets in code |
|
|
127
|
-
| 3 | Injection | Parameterized queries, input validation |
|
|
128
|
-
| 4 | Insecure Design | Threat modeling, spec-driven development |
|
|
129
|
-
| 5 | Security Misconfiguration | Security headers, minimal permissions, audit deps |
|
|
130
|
-
| 6 | Vulnerable Components | `npm audit`, keep deps updated, minimal deps |
|
|
131
|
-
| 7 | Auth Failures | Strong passwords, rate limiting, session management |
|
|
132
|
-
| 8 | Data Integrity Failures | Verify updates/dependencies, signed artifacts |
|
|
133
|
-
| 9 | Logging Failures | Log security events, don't log secrets |
|
|
134
|
-
| 10 | SSRF | Validate/allowlist URLs, restrict outbound requests |
|