@comfanion/workflow 4.36.45 → 4.36.46

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.
@@ -0,0 +1,325 @@
1
+ # Security Standards
2
+
3
+ **Project:** {{project_name}}
4
+ **Version:** 1.0
5
+ **Last Updated:** {{date}}
6
+
7
+ ---
8
+
9
+ ## Overview
10
+
11
+ Security is a first-class concern in this project. Every developer must follow these guidelines.
12
+
13
+ ---
14
+
15
+ ## OWASP Top 10 Mitigations
16
+
17
+ ### 1. Injection (SQL, NoSQL, Command)
18
+
19
+ **Rule:** Never concatenate user input into queries.
20
+
21
+ ```typescript
22
+ // ❌ BAD - SQL Injection
23
+ const query = `SELECT * FROM users WHERE id = '${userId}'`;
24
+
25
+ // ✅ GOOD - Parameterized query
26
+ const query = `SELECT * FROM users WHERE id = $1`;
27
+ await db.query(query, [userId]);
28
+ ```
29
+
30
+ ### 2. Broken Authentication
31
+
32
+ **Rules:**
33
+ - Use industry-standard auth (OAuth2, JWT)
34
+ - Implement rate limiting on auth endpoints
35
+ - Use secure password hashing (bcrypt, Argon2)
36
+ - Session tokens must be unpredictable
37
+
38
+ ```typescript
39
+ // ✅ GOOD - Secure password hashing
40
+ import { hash, verify } from 'argon2';
41
+ const hashedPassword = await hash(password);
42
+ ```
43
+
44
+ ### 3. Sensitive Data Exposure
45
+
46
+ **Rules:**
47
+ - Encrypt sensitive data at rest
48
+ - Use HTTPS for all communications
49
+ - Never log PII, passwords, tokens, or API keys
50
+ - Mask sensitive data in error messages
51
+
52
+ ```typescript
53
+ // ❌ BAD - Logging sensitive data
54
+ console.log(`User login: ${email}, password: ${password}`);
55
+
56
+ // ✅ GOOD - Masked logging
57
+ console.log(`User login attempt: ${email.slice(0, 3)}***`);
58
+ ```
59
+
60
+ ### 4. XML External Entities (XXE)
61
+
62
+ **Rule:** Disable external entity processing in XML parsers.
63
+
64
+ ### 5. Broken Access Control
65
+
66
+ **Rules:**
67
+ - Verify user owns the resource before access
68
+ - Use principle of least privilege
69
+ - Deny by default
70
+
71
+ ```typescript
72
+ // ✅ GOOD - Verify ownership
73
+ async function getTask(userId: string, taskId: string) {
74
+ const task = await db.findTask(taskId);
75
+ if (task.ownerId !== userId) {
76
+ throw new ForbiddenError('Access denied');
77
+ }
78
+ return task;
79
+ }
80
+ ```
81
+
82
+ ### 6. Security Misconfiguration
83
+
84
+ **Rules:**
85
+ - Remove default credentials
86
+ - Disable debug mode in production
87
+ - Keep dependencies updated
88
+ - Use security headers (CSP, HSTS, X-Frame-Options)
89
+
90
+ ### 7. Cross-Site Scripting (XSS)
91
+
92
+ **Rules:**
93
+ - Escape all output
94
+ - Use Content Security Policy
95
+ - Validate and sanitize HTML input
96
+
97
+ ```typescript
98
+ // ✅ GOOD - Escape output (React does this by default)
99
+ return <div>{userInput}</div>;
100
+
101
+ // ⚠️ DANGEROUS - Only if absolutely necessary
102
+ return <div dangerouslySetInnerHTML={{__html: sanitized}} />;
103
+ ```
104
+
105
+ ### 8. Insecure Deserialization
106
+
107
+ **Rule:** Validate deserialized data, use safe parsers.
108
+
109
+ ### 9. Using Components with Known Vulnerabilities
110
+
111
+ **Rules:**
112
+ - Run `npm audit` / `snyk` regularly
113
+ - Keep dependencies updated
114
+ - Remove unused dependencies
115
+
116
+ ### 10. Insufficient Logging & Monitoring
117
+
118
+ **Rules:**
119
+ - Log security events (login, logout, failed auth)
120
+ - Include timestamp, user ID, action, result
121
+ - Don't log sensitive data
122
+ - Set up alerts for suspicious activity
123
+
124
+ ---
125
+
126
+ ## Input Validation
127
+
128
+ ### All User Input Must Be Validated
129
+
130
+ ```typescript
131
+ import { z } from 'zod';
132
+
133
+ const CreateUserSchema = z.object({
134
+ email: z.string().email().max(255),
135
+ name: z.string().min(1).max(100),
136
+ age: z.number().int().min(0).max(150),
137
+ });
138
+
139
+ function createUser(input: unknown) {
140
+ const validated = CreateUserSchema.parse(input);
141
+ // Now safe to use
142
+ }
143
+ ```
144
+
145
+ ### Validate At System Boundaries
146
+
147
+ - HTTP handlers (API input)
148
+ - Message queue consumers
149
+ - File uploads
150
+ - External API responses
151
+
152
+ ---
153
+
154
+ ## Secrets Management
155
+
156
+ ### Never Hardcode Secrets
157
+
158
+ ```typescript
159
+ // ❌ BAD
160
+ const apiKey = 'sk-1234567890abcdef';
161
+
162
+ // ✅ GOOD
163
+ const apiKey = process.env.API_KEY;
164
+ ```
165
+
166
+ ### Environment Variables
167
+
168
+ ```bash
169
+ # .env.example (commit this)
170
+ DATABASE_URL=
171
+ API_KEY=
172
+ JWT_SECRET=
173
+
174
+ # .env (NEVER commit)
175
+ DATABASE_URL=postgres://...
176
+ API_KEY=sk-...
177
+ JWT_SECRET=...
178
+ ```
179
+
180
+ ### Gitignore
181
+
182
+ ```
183
+ # Always ignore
184
+ .env
185
+ .env.local
186
+ *.pem
187
+ *.key
188
+ secrets/
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Authentication & Authorization
194
+
195
+ ### JWT Best Practices
196
+
197
+ ```typescript
198
+ // ✅ GOOD JWT configuration
199
+ const token = jwt.sign(
200
+ { userId, role },
201
+ process.env.JWT_SECRET,
202
+ {
203
+ expiresIn: '1h', // Short expiration
204
+ algorithm: 'HS256', // Or RS256 for asymmetric
205
+ issuer: 'our-app',
206
+ audience: 'our-app',
207
+ }
208
+ );
209
+ ```
210
+
211
+ ### Authorization Middleware
212
+
213
+ ```typescript
214
+ // ✅ GOOD - Check permissions before action
215
+ async function deleteTask(user: User, taskId: string) {
216
+ const task = await taskRepo.find(taskId);
217
+
218
+ if (!task) throw new NotFoundError();
219
+ if (task.ownerId !== user.id && !user.isAdmin) {
220
+ throw new ForbiddenError();
221
+ }
222
+
223
+ await taskRepo.delete(taskId);
224
+ }
225
+ ```
226
+
227
+ ---
228
+
229
+ ## API Security
230
+
231
+ ### Rate Limiting
232
+
233
+ ```typescript
234
+ // Apply to auth endpoints
235
+ app.use('/api/auth', rateLimit({
236
+ windowMs: 15 * 60 * 1000, // 15 minutes
237
+ max: 10, // 10 requests per window
238
+ }));
239
+ ```
240
+
241
+ ### Security Headers
242
+
243
+ ```typescript
244
+ import helmet from 'helmet';
245
+
246
+ app.use(helmet({
247
+ contentSecurityPolicy: true,
248
+ crossOriginEmbedderPolicy: true,
249
+ crossOriginOpenerPolicy: true,
250
+ crossOriginResourcePolicy: true,
251
+ dnsPrefetchControl: true,
252
+ frameguard: true,
253
+ hidePoweredBy: true,
254
+ hsts: true,
255
+ ieNoOpen: true,
256
+ noSniff: true,
257
+ originAgentCluster: true,
258
+ permittedCrossDomainPolicies: true,
259
+ referrerPolicy: true,
260
+ xssFilter: true,
261
+ }));
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Database Security
267
+
268
+ ### Parameterized Queries
269
+
270
+ ```typescript
271
+ // ✅ Always use parameterized queries
272
+ const result = await db.query(
273
+ 'SELECT * FROM users WHERE email = $1 AND active = $2',
274
+ [email, true]
275
+ );
276
+ ```
277
+
278
+ ### Principle of Least Privilege
279
+
280
+ - App database user should NOT have DROP, CREATE permissions
281
+ - Use read-only replicas for reporting
282
+
283
+ ---
284
+
285
+ ## File Upload Security
286
+
287
+ ```typescript
288
+ // ✅ GOOD - Validate uploads
289
+ const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
290
+ const maxSize = 5 * 1024 * 1024; // 5MB
291
+
292
+ function validateUpload(file: UploadedFile) {
293
+ if (!allowedTypes.includes(file.mimetype)) {
294
+ throw new BadRequestError('Invalid file type');
295
+ }
296
+ if (file.size > maxSize) {
297
+ throw new BadRequestError('File too large');
298
+ }
299
+ // Generate random filename to prevent path traversal
300
+ const safeFilename = `${uuid()}.${extension}`;
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ## Security Checklist for Code Review
307
+
308
+ - [ ] No hardcoded secrets or API keys
309
+ - [ ] All user inputs validated
310
+ - [ ] Using parameterized queries
311
+ - [ ] Authentication required on protected endpoints
312
+ - [ ] Authorization checks before data access
313
+ - [ ] Sensitive data not logged
314
+ - [ ] Error messages don't leak internal details
315
+ - [ ] Dependencies don't have known vulnerabilities
316
+ - [ ] Security headers configured
317
+ - [ ] Rate limiting on sensitive endpoints
318
+
319
+ ---
320
+
321
+ ## Changelog
322
+
323
+ | Version | Date | Author | Changes |
324
+ |---------|------|--------|---------|
325
+ | 1.0 | {{date}} | {{author}} | Initial security standards |
@@ -489,11 +489,57 @@ Read from `config.yaml → development.methodology`:
489
489
  - Tasks completed: {{completed_tasks_count}}
490
490
  - Tests added: {{new_tests_count}}
491
491
  - Files changed: {{changed_files_count}}
492
-
493
- **Next Steps:**
494
- - Run `code-review` skill for peer review
495
- - After approval, mark story as "done"
496
492
  </output>
493
+
494
+ <!-- AUTO-INVOKE: @reviewer for code review -->
495
+ <goto step="8">Automatic code review</goto>
496
+ </step>
497
+ ```
498
+
499
+ ### Step 8: Automatic Code Review (by @reviewer)
500
+
501
+ ```xml
502
+ <step n="8" goal="Automatic security and quality review before done">
503
+ <critical>ALWAYS invoke @reviewer after all tasks complete</critical>
504
+
505
+ <action>Invoke @reviewer agent with story path</action>
506
+ <action>@reviewer uses GPT-5.2 Codex for deep analysis</action>
507
+
508
+ <invoke agent="reviewer">
509
+ <param name="story_path">{{story_path}}</param>
510
+ <param name="files_changed">{{file_list}}</param>
511
+ <param name="focus">security, correctness, test coverage</param>
512
+ </invoke>
513
+
514
+ <check if="reviewer verdict = APPROVE">
515
+ <action>Mark story status as "done"</action>
516
+ <output>✅ Code review passed! Story complete.</output>
517
+ </check>
518
+
519
+ <check if="reviewer verdict = CHANGES_REQUESTED">
520
+ <action>Create follow-up tasks from review findings</action>
521
+ <action>Add tasks to story file</action>
522
+ <output>
523
+ 🔄 **Code Review: Changes Requested**
524
+
525
+ Review found {{issues_count}} issues to fix.
526
+ New tasks added to story.
527
+
528
+ Run dev-story again to fix issues.
529
+ </output>
530
+ <goto step="4">Fix review issues</goto>
531
+ </check>
532
+
533
+ <check if="reviewer verdict = BLOCKED">
534
+ <action>Mark story status as "blocked"</action>
535
+ <output>
536
+ ❌ **Code Review: Blocked**
537
+
538
+ Critical issues found. See review for details.
539
+ Cannot proceed until blocking issues resolved.
540
+ </output>
541
+ <halt reason="Blocked by code review"/>
542
+ </check>
497
543
  </step>
498
544
  ```
499
545
 
@@ -519,6 +565,7 @@ Read from `config.yaml → development.methodology`:
519
565
 
520
566
  - [ ] All tasks/subtasks marked complete
521
567
  - [ ] Implementation satisfies every AC
568
+ - [ ] Security checklist passed
522
569
  - [ ] Unit tests added for core functionality
523
570
  - [ ] Integration tests added when required
524
571
  - [ ] All tests pass (no regressions)
@@ -526,4 +573,5 @@ Read from `config.yaml → development.methodology`:
526
573
  - [ ] File List includes all changes
527
574
  - [ ] Dev Agent Record complete
528
575
  - [ ] Change Log updated
529
- - [ ] Status set to "review"
576
+ - [ ] **@reviewer approved** (auto-invoked after Step 7)
577
+ - [ ] Status set to "done"
@@ -204,10 +204,26 @@ Story is complete when:
204
204
 
205
205
  ---
206
206
 
207
+ ## Security Checklist
208
+
209
+ Before marking story as done, verify:
210
+
211
+ - [ ] **Input Validation**: All user inputs validated/sanitized
212
+ - [ ] **Authentication**: Protected endpoints require auth
213
+ - [ ] **Authorization**: User can only access their own data
214
+ - [ ] **Secrets**: No hardcoded passwords, tokens, API keys
215
+ - [ ] **SQL Injection**: Using parameterized queries / ORM
216
+ - [ ] **XSS**: Output properly escaped (if frontend)
217
+ - [ ] **Sensitive Data**: PII/secrets not logged
218
+ - [ ] **Error Messages**: No sensitive info in error responses
219
+
220
+ ---
221
+
207
222
  ## Definition of Done
208
223
 
209
224
  - [ ] All acceptance criteria met
210
225
  - [ ] All tasks completed
226
+ - [ ] Security checklist passed
211
227
  - [ ] Code follows `docs/coding-standards/`
212
228
  - [ ] Tests pass
213
229
  - [ ] Code reviewed