@mytechtoday/augment-extensions 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/AGENTS.md +83 -3
  2. package/README.md +6 -5
  3. package/augment-extensions/coding-standards/python/README.md +44 -0
  4. package/augment-extensions/coding-standards/python/module.json +26 -0
  5. package/augment-extensions/coding-standards/python/rules/best-practices.md +232 -0
  6. package/augment-extensions/coding-standards/python/rules/code-organization.md +220 -0
  7. package/augment-extensions/coding-standards/python/rules/error-handling.md +221 -0
  8. package/augment-extensions/coding-standards/python/rules/naming-conventions.md +172 -0
  9. package/augment-extensions/coding-standards/python/rules/type-hints.md +188 -0
  10. package/augment-extensions/coding-standards/react/README.md +45 -0
  11. package/augment-extensions/coding-standards/react/module.json +27 -0
  12. package/augment-extensions/coding-standards/react/rules/component-patterns.md +214 -0
  13. package/augment-extensions/coding-standards/react/rules/hooks-best-practices.md +235 -0
  14. package/augment-extensions/coding-standards/react/rules/performance.md +300 -0
  15. package/augment-extensions/coding-standards/react/rules/state-management.md +265 -0
  16. package/augment-extensions/coding-standards/react/rules/typescript-react.md +271 -0
  17. package/augment-extensions/domain-rules/api-design/README.md +41 -0
  18. package/augment-extensions/domain-rules/api-design/module.json +27 -0
  19. package/augment-extensions/domain-rules/api-design/rules/authentication.md +263 -0
  20. package/augment-extensions/domain-rules/api-design/rules/documentation.md +395 -0
  21. package/augment-extensions/domain-rules/api-design/rules/error-handling.md +290 -0
  22. package/augment-extensions/domain-rules/api-design/rules/graphql-api.md +313 -0
  23. package/augment-extensions/domain-rules/api-design/rules/rest-api.md +214 -0
  24. package/augment-extensions/domain-rules/api-design/rules/versioning.md +268 -0
  25. package/augment-extensions/domain-rules/security/README.md +41 -0
  26. package/augment-extensions/domain-rules/security/module.json +28 -0
  27. package/augment-extensions/domain-rules/security/rules/authentication-security.md +361 -0
  28. package/augment-extensions/domain-rules/security/rules/encryption.md +208 -0
  29. package/augment-extensions/domain-rules/security/rules/input-validation.md +294 -0
  30. package/augment-extensions/domain-rules/security/rules/owasp-top-10.md +339 -0
  31. package/augment-extensions/domain-rules/security/rules/secure-coding.md +293 -0
  32. package/augment-extensions/domain-rules/security/rules/web-security.md +268 -0
  33. package/augment-extensions/examples/design-patterns/README.md +37 -0
  34. package/augment-extensions/examples/design-patterns/examples/behavioral-patterns.md +370 -0
  35. package/augment-extensions/examples/design-patterns/examples/creational-patterns.md +250 -0
  36. package/augment-extensions/examples/design-patterns/examples/structural-patterns.md +264 -0
  37. package/augment-extensions/examples/design-patterns/module.json +27 -0
  38. package/{modules → augment-extensions}/workflows/beads/examples/complete-workflow-example.md +5 -5
  39. package/{modules → augment-extensions}/workflows/beads/rules/file-format.md +45 -1
  40. package/{modules → augment-extensions}/workflows/beads/rules/workflow.md +41 -0
  41. package/{modules → augment-extensions}/workflows/openspec/examples/complete-change-example.md +14 -0
  42. package/{modules → augment-extensions}/workflows/openspec/rules/spec-format.md +44 -1
  43. package/{modules → augment-extensions}/workflows/openspec/rules/workflow.md +25 -0
  44. package/cli/dist/cli.js +69 -1
  45. package/cli/dist/cli.js.map +1 -1
  46. package/cli/dist/commands/coord.d.ts +30 -0
  47. package/cli/dist/commands/coord.d.ts.map +1 -0
  48. package/cli/dist/commands/coord.js +150 -0
  49. package/cli/dist/commands/coord.js.map +1 -0
  50. package/cli/dist/commands/link.js +1 -1
  51. package/cli/dist/commands/link.js.map +1 -1
  52. package/cli/dist/commands/list.js +1 -1
  53. package/cli/dist/commands/list.js.map +1 -1
  54. package/cli/dist/commands/search.d.ts.map +1 -1
  55. package/cli/dist/commands/search.js +107 -5
  56. package/cli/dist/commands/search.js.map +1 -1
  57. package/cli/dist/commands/show.js +1 -1
  58. package/cli/dist/commands/show.js.map +1 -1
  59. package/cli/dist/commands/sync.d.ts +26 -0
  60. package/cli/dist/commands/sync.d.ts.map +1 -0
  61. package/cli/dist/commands/sync.js +106 -0
  62. package/cli/dist/commands/sync.js.map +1 -0
  63. package/cli/dist/commands/update.d.ts.map +1 -1
  64. package/cli/dist/commands/update.js +132 -7
  65. package/cli/dist/commands/update.js.map +1 -1
  66. package/cli/dist/utils/auto-sync.d.ts +34 -0
  67. package/cli/dist/utils/auto-sync.d.ts.map +1 -0
  68. package/cli/dist/utils/auto-sync.js +172 -0
  69. package/cli/dist/utils/auto-sync.js.map +1 -0
  70. package/cli/dist/utils/beads-sync.d.ts +51 -0
  71. package/cli/dist/utils/beads-sync.d.ts.map +1 -0
  72. package/cli/dist/utils/beads-sync.js +171 -0
  73. package/cli/dist/utils/beads-sync.js.map +1 -0
  74. package/cli/dist/utils/coordination-queries.d.ts +79 -0
  75. package/cli/dist/utils/coordination-queries.d.ts.map +1 -0
  76. package/cli/dist/utils/coordination-queries.js +155 -0
  77. package/cli/dist/utils/coordination-queries.js.map +1 -0
  78. package/cli/dist/utils/file-tracking.d.ts +42 -0
  79. package/cli/dist/utils/file-tracking.d.ts.map +1 -0
  80. package/cli/dist/utils/file-tracking.js +155 -0
  81. package/cli/dist/utils/file-tracking.js.map +1 -0
  82. package/cli/dist/utils/migrate.d.ts +25 -0
  83. package/cli/dist/utils/migrate.d.ts.map +1 -0
  84. package/cli/dist/utils/migrate.js +204 -0
  85. package/cli/dist/utils/migrate.js.map +1 -0
  86. package/cli/dist/utils/openspec-sync.d.ts +48 -0
  87. package/cli/dist/utils/openspec-sync.d.ts.map +1 -0
  88. package/cli/dist/utils/openspec-sync.js +167 -0
  89. package/cli/dist/utils/openspec-sync.js.map +1 -0
  90. package/{MODULES.md → modules.md} +1 -1
  91. package/package.json +9 -7
  92. /package/{modules → augment-extensions}/coding-standards/typescript/README.md +0 -0
  93. /package/{modules → augment-extensions}/coding-standards/typescript/module.json +0 -0
  94. /package/{modules → augment-extensions}/coding-standards/typescript/rules/naming-conventions.md +0 -0
  95. /package/{modules → augment-extensions}/workflows/beads/README.md +0 -0
  96. /package/{modules → augment-extensions}/workflows/beads/module.json +0 -0
  97. /package/{modules → augment-extensions}/workflows/beads/rules/best-practices.md +0 -0
  98. /package/{modules → augment-extensions}/workflows/beads/rules/manual-setup.md +0 -0
  99. /package/{modules → augment-extensions}/workflows/openspec/README.md +0 -0
  100. /package/{modules → augment-extensions}/workflows/openspec/module.json +0 -0
  101. /package/{modules → augment-extensions}/workflows/openspec/rules/best-practices.md +0 -0
  102. /package/{modules → augment-extensions}/workflows/openspec/rules/manual-setup.md +0 -0
@@ -0,0 +1,339 @@
1
+ # OWASP Top 10 Vulnerabilities
2
+
3
+ Mitigations for the OWASP Top 10 web application security risks.
4
+
5
+ ## A01:2021 - Broken Access Control
6
+
7
+ Unauthorized access to resources or functions.
8
+
9
+ ```typescript
10
+ // Bad - No authorization check
11
+ app.get('/api/users/:id', async (req, res) => {
12
+ const user = await db.users.findOne(req.params.id);
13
+ res.json(user);
14
+ });
15
+
16
+ // Good - Check authorization
17
+ app.get('/api/users/:id', authenticate, async (req, res) => {
18
+ const user = await db.users.findOne(req.params.id);
19
+
20
+ // Users can only access their own data (unless admin)
21
+ if (user.id !== req.user.id && req.user.role !== 'admin') {
22
+ return res.status(403).json({ error: 'Forbidden' });
23
+ }
24
+
25
+ res.json(user);
26
+ });
27
+
28
+ // Good - Use middleware for authorization
29
+ const authorize = (permission: string) => {
30
+ return (req, res, next) => {
31
+ if (!req.user.permissions.includes(permission)) {
32
+ return res.status(403).json({ error: 'Insufficient permissions' });
33
+ }
34
+ next();
35
+ };
36
+ };
37
+
38
+ app.delete('/api/users/:id', authenticate, authorize('delete:users'), async (req, res) => {
39
+ await db.users.delete(req.params.id);
40
+ res.status(204).send();
41
+ });
42
+ ```
43
+
44
+ ## A02:2021 - Cryptographic Failures
45
+
46
+ Sensitive data exposure due to weak cryptography.
47
+
48
+ ```typescript
49
+ // Bad - Storing passwords in plain text
50
+ await db.users.create({
51
+ email: 'user@example.com',
52
+ password: 'secret123' // ❌ Never store plain text passwords
53
+ });
54
+
55
+ // Good - Hash passwords with bcrypt
56
+ import bcrypt from 'bcrypt';
57
+
58
+ const hashedPassword = await bcrypt.hash(password, 10);
59
+ await db.users.create({
60
+ email: 'user@example.com',
61
+ password: hashedPassword
62
+ });
63
+
64
+ // Good - Verify password
65
+ const isValid = await bcrypt.compare(inputPassword, user.password);
66
+
67
+ // Bad - Weak encryption
68
+ const encrypted = Buffer.from(data).toString('base64'); // ❌ Not encryption
69
+
70
+ // Good - Use proper encryption
71
+ import crypto from 'crypto';
72
+
73
+ const algorithm = 'aes-256-gcm';
74
+ const key = crypto.randomBytes(32);
75
+ const iv = crypto.randomBytes(16);
76
+
77
+ const cipher = crypto.createCipheriv(algorithm, key, iv);
78
+ let encrypted = cipher.update(data, 'utf8', 'hex');
79
+ encrypted += cipher.final('hex');
80
+ const authTag = cipher.getAuthTag();
81
+ ```
82
+
83
+ ## A03:2021 - Injection
84
+
85
+ SQL, NoSQL, OS command injection attacks.
86
+
87
+ ```typescript
88
+ // Bad - SQL injection vulnerability
89
+ app.get('/users', async (req, res) => {
90
+ const query = `SELECT * FROM users WHERE name = '${req.query.name}'`;
91
+ const users = await db.query(query); // ❌ Vulnerable to SQL injection
92
+ });
93
+
94
+ // Good - Use parameterized queries
95
+ app.get('/users', async (req, res) => {
96
+ const users = await db.query(
97
+ 'SELECT * FROM users WHERE name = $1',
98
+ [req.query.name]
99
+ );
100
+ });
101
+
102
+ // Good - Use ORM
103
+ const users = await db.users.findMany({
104
+ where: { name: req.query.name }
105
+ });
106
+
107
+ // Bad - Command injection
108
+ const { exec } = require('child_process');
109
+ exec(`ping ${req.query.host}`); // ❌ Vulnerable to command injection
110
+
111
+ // Good - Validate and sanitize input
112
+ const host = req.query.host;
113
+ if (!/^[a-zA-Z0-9.-]+$/.test(host)) {
114
+ return res.status(400).json({ error: 'Invalid host' });
115
+ }
116
+ exec(`ping ${host}`);
117
+
118
+ // Better - Use safe alternatives
119
+ import { ping } from 'ping';
120
+ const result = await ping.promise.probe(req.query.host);
121
+ ```
122
+
123
+ ## A04:2021 - Insecure Design
124
+
125
+ Flaws in design and architecture.
126
+
127
+ ```typescript
128
+ // Bad - No rate limiting
129
+ app.post('/api/login', async (req, res) => {
130
+ const user = await authenticate(req.body.email, req.body.password);
131
+ // ❌ Allows brute force attacks
132
+ });
133
+
134
+ // Good - Implement rate limiting
135
+ import rateLimit from 'express-rate-limit';
136
+
137
+ const loginLimiter = rateLimit({
138
+ windowMs: 15 * 60 * 1000, // 15 minutes
139
+ max: 5, // 5 attempts
140
+ message: 'Too many login attempts, please try again later'
141
+ });
142
+
143
+ app.post('/api/login', loginLimiter, async (req, res) => {
144
+ const user = await authenticate(req.body.email, req.body.password);
145
+ });
146
+
147
+ // Good - Implement account lockout
148
+ const MAX_ATTEMPTS = 5;
149
+ const LOCKOUT_TIME = 15 * 60 * 1000; // 15 minutes
150
+
151
+ if (user.loginAttempts >= MAX_ATTEMPTS) {
152
+ const timeSinceLastAttempt = Date.now() - user.lastLoginAttempt;
153
+ if (timeSinceLastAttempt < LOCKOUT_TIME) {
154
+ return res.status(429).json({ error: 'Account locked' });
155
+ }
156
+ }
157
+ ```
158
+
159
+ ## A05:2021 - Security Misconfiguration
160
+
161
+ Insecure default configurations.
162
+
163
+ ```typescript
164
+ // Bad - Exposing error details in production
165
+ app.use((err, req, res, next) => {
166
+ res.status(500).json({
167
+ error: err.message,
168
+ stack: err.stack // ❌ Exposes internal details
169
+ });
170
+ });
171
+
172
+ // Good - Hide details in production
173
+ app.use((err, req, res, next) => {
174
+ console.error(err); // Log server-side
175
+
176
+ if (process.env.NODE_ENV === 'production') {
177
+ res.status(500).json({ error: 'Internal server error' });
178
+ } else {
179
+ res.status(500).json({ error: err.message, stack: err.stack });
180
+ }
181
+ });
182
+
183
+ // Bad - Default credentials
184
+ const dbConfig = {
185
+ user: 'admin',
186
+ password: 'admin' // ❌ Default credentials
187
+ };
188
+
189
+ // Good - Use environment variables
190
+ const dbConfig = {
191
+ user: process.env.DB_USER,
192
+ password: process.env.DB_PASSWORD
193
+ };
194
+
195
+ // Good - Security headers
196
+ import helmet from 'helmet';
197
+ app.use(helmet());
198
+ ```
199
+
200
+ ## A06:2021 - Vulnerable and Outdated Components
201
+
202
+ Using components with known vulnerabilities.
203
+
204
+ ```bash
205
+ # Good - Regularly update dependencies
206
+ npm audit
207
+ npm audit fix
208
+
209
+ # Good - Use automated tools
210
+ npm install -g npm-check-updates
211
+ ncu -u
212
+ npm install
213
+
214
+ # Good - Monitor for vulnerabilities
215
+ # Use Dependabot, Snyk, or similar tools
216
+ ```
217
+
218
+ ## A07:2021 - Identification and Authentication Failures
219
+
220
+ Weak authentication mechanisms.
221
+
222
+ ```typescript
223
+ // Bad - Weak password requirements
224
+ if (password.length < 6) { // ❌ Too weak
225
+ return res.status(400).json({ error: 'Password too short' });
226
+ }
227
+
228
+ // Good - Strong password requirements
229
+ const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{12,}$/;
230
+ if (!passwordRegex.test(password)) {
231
+ return res.status(400).json({
232
+ error: 'Password must be at least 12 characters with uppercase, lowercase, number, and special character'
233
+ });
234
+ }
235
+
236
+ // Good - Implement MFA
237
+ const mfaToken = speakeasy.totp({
238
+ secret: user.mfaSecret,
239
+ encoding: 'base32'
240
+ });
241
+
242
+ if (req.body.mfaCode !== mfaToken) {
243
+ return res.status(401).json({ error: 'Invalid MFA code' });
244
+ }
245
+ ```
246
+
247
+ ## A08:2021 - Software and Data Integrity Failures
248
+
249
+ Insecure CI/CD, updates, or deserialization.
250
+
251
+ ```typescript
252
+ // Bad - Unsafe deserialization
253
+ const userData = eval(req.body.data); // ❌ Never use eval
254
+
255
+ // Good - Safe JSON parsing
256
+ try {
257
+ const userData = JSON.parse(req.body.data);
258
+ } catch (error) {
259
+ return res.status(400).json({ error: 'Invalid JSON' });
260
+ }
261
+
262
+ // Good - Verify package integrity
263
+ # package-lock.json ensures integrity
264
+ npm ci # Use in CI/CD instead of npm install
265
+ ```
266
+
267
+ ## A09:2021 - Security Logging and Monitoring Failures
268
+
269
+ Insufficient logging and monitoring.
270
+
271
+ ```typescript
272
+ // Good - Log security events
273
+ import winston from 'winston';
274
+
275
+ const logger = winston.createLogger({
276
+ level: 'info',
277
+ format: winston.format.json(),
278
+ transports: [
279
+ new winston.transports.File({ filename: 'security.log' })
280
+ ]
281
+ });
282
+
283
+ // Log authentication attempts
284
+ logger.info('Login attempt', {
285
+ email: req.body.email,
286
+ ip: req.ip,
287
+ userAgent: req.headers['user-agent'],
288
+ success: true
289
+ });
290
+
291
+ // Log authorization failures
292
+ logger.warn('Authorization failed', {
293
+ userId: req.user.id,
294
+ resource: req.path,
295
+ action: req.method,
296
+ ip: req.ip
297
+ });
298
+ ```
299
+
300
+ ## A10:2021 - Server-Side Request Forgery (SSRF)
301
+
302
+ Fetching remote resources without validation.
303
+
304
+ ```typescript
305
+ // Bad - SSRF vulnerability
306
+ app.get('/fetch', async (req, res) => {
307
+ const response = await fetch(req.query.url); // ❌ Allows SSRF
308
+ res.send(await response.text());
309
+ });
310
+
311
+ // Good - Validate URL
312
+ const allowedDomains = ['api.example.com', 'cdn.example.com'];
313
+
314
+ const url = new URL(req.query.url);
315
+ if (!allowedDomains.includes(url.hostname)) {
316
+ return res.status(400).json({ error: 'Invalid domain' });
317
+ }
318
+
319
+ // Good - Block private IPs
320
+ import isPrivateIp from 'private-ip';
321
+
322
+ if (isPrivateIp(url.hostname)) {
323
+ return res.status(400).json({ error: 'Private IPs not allowed' });
324
+ }
325
+ ```
326
+
327
+ ## Best Practices
328
+
329
+ 1. **Implement proper access control** - Check authorization
330
+ 2. **Use strong encryption** - Protect sensitive data
331
+ 3. **Prevent injection** - Use parameterized queries
332
+ 4. **Design securely** - Security by design
333
+ 5. **Configure securely** - No default credentials
334
+ 6. **Update dependencies** - Patch vulnerabilities
335
+ 7. **Strong authentication** - MFA, strong passwords
336
+ 8. **Verify integrity** - Check package integrity
337
+ 9. **Log security events** - Monitor for attacks
338
+ 10. **Prevent SSRF** - Validate URLs and IPs
339
+
@@ -0,0 +1,293 @@
1
+ # Secure Coding Practices
2
+
3
+ General secure coding practices for building secure applications.
4
+
5
+ ## Principle of Least Privilege
6
+
7
+ Grant minimum necessary permissions.
8
+
9
+ ```typescript
10
+ // Bad - Overly permissive
11
+ const user = {
12
+ id: '123',
13
+ role: 'admin', // ❌ Everyone is admin
14
+ permissions: ['*'] // ❌ All permissions
15
+ };
16
+
17
+ // Good - Specific permissions
18
+ const user = {
19
+ id: '123',
20
+ role: 'editor',
21
+ permissions: ['read:posts', 'write:posts', 'read:users']
22
+ };
23
+
24
+ // Good - Check specific permission
25
+ const hasPermission = (user: User, permission: string): boolean => {
26
+ return user.permissions.includes(permission);
27
+ };
28
+
29
+ if (!hasPermission(req.user, 'delete:posts')) {
30
+ return res.status(403).json({ error: 'Forbidden' });
31
+ }
32
+ ```
33
+
34
+ ## Defense in Depth
35
+
36
+ Implement multiple layers of security.
37
+
38
+ ```typescript
39
+ // Layer 1: Input validation
40
+ const schema = z.object({
41
+ email: z.string().email(),
42
+ content: z.string().max(1000)
43
+ });
44
+ const data = schema.parse(req.body);
45
+
46
+ // Layer 2: Authentication
47
+ if (!req.user) {
48
+ return res.status(401).json({ error: 'Unauthorized' });
49
+ }
50
+
51
+ // Layer 3: Authorization
52
+ if (req.user.id !== post.authorId && req.user.role !== 'admin') {
53
+ return res.status(403).json({ error: 'Forbidden' });
54
+ }
55
+
56
+ // Layer 4: Rate limiting
57
+ // Layer 5: Sanitization
58
+ const sanitized = DOMPurify.sanitize(data.content);
59
+
60
+ // Layer 6: Logging
61
+ logger.info('Post updated', { userId: req.user.id, postId: post.id });
62
+ ```
63
+
64
+ ## Secure Defaults
65
+
66
+ Use secure configurations by default.
67
+
68
+ ```typescript
69
+ // Good - Secure defaults
70
+ const config = {
71
+ https: true,
72
+ httpOnly: true,
73
+ sameSite: 'strict',
74
+ secure: true,
75
+ maxAge: 3600000,
76
+ ...userConfig // Allow override if needed
77
+ };
78
+
79
+ // Bad - Insecure defaults
80
+ const config = {
81
+ https: false, // ❌
82
+ httpOnly: false, // ❌
83
+ ...userConfig
84
+ };
85
+ ```
86
+
87
+ ## Fail Securely
88
+
89
+ Handle errors without exposing sensitive information.
90
+
91
+ ```typescript
92
+ // Bad - Exposing internal details
93
+ try {
94
+ const user = await db.users.findOne(userId);
95
+ } catch (error) {
96
+ res.status(500).json({
97
+ error: error.message, // ❌ May expose DB details
98
+ stack: error.stack // ❌ Exposes code structure
99
+ });
100
+ }
101
+
102
+ // Good - Generic error message
103
+ try {
104
+ const user = await db.users.findOne(userId);
105
+ } catch (error) {
106
+ logger.error('Database error', { error, userId }); // Log internally
107
+ res.status(500).json({ error: 'Internal server error' }); // Generic message
108
+ }
109
+ ```
110
+
111
+ ## Don't Trust Client Data
112
+
113
+ Always validate on server side.
114
+
115
+ ```typescript
116
+ // Bad - Trusting client
117
+ app.post('/purchase', async (req, res) => {
118
+ const { productId, price } = req.body; // ❌ Client sends price
119
+ await processPayment(price);
120
+ });
121
+
122
+ // Good - Verify on server
123
+ app.post('/purchase', async (req, res) => {
124
+ const { productId } = req.body;
125
+ const product = await db.products.findOne(productId);
126
+ await processPayment(product.price); // ✅ Use server price
127
+ });
128
+ ```
129
+
130
+ ## Avoid Security by Obscurity
131
+
132
+ Don't rely on secrecy of implementation.
133
+
134
+ ```typescript
135
+ // Bad - Security by obscurity
136
+ const isAdmin = (user) => {
137
+ return user.secretAdminFlag === 'xK9mP2qL'; // ❌ Weak
138
+ };
139
+
140
+ // Good - Proper authorization
141
+ const isAdmin = (user) => {
142
+ return user.role === 'admin' && user.verified === true;
143
+ };
144
+ ```
145
+
146
+ ## Secure Error Messages
147
+
148
+ Don't leak information through error messages.
149
+
150
+ ```typescript
151
+ // Bad - Information leakage
152
+ app.post('/login', async (req, res) => {
153
+ const user = await db.users.findOne({ email: req.body.email });
154
+
155
+ if (!user) {
156
+ return res.status(401).json({ error: 'Email not found' }); // ❌ Reveals email exists
157
+ }
158
+
159
+ if (!await bcrypt.compare(req.body.password, user.password)) {
160
+ return res.status(401).json({ error: 'Incorrect password' }); // ❌ Reveals email exists
161
+ }
162
+ });
163
+
164
+ // Good - Generic error message
165
+ app.post('/login', async (req, res) => {
166
+ const user = await db.users.findOne({ email: req.body.email });
167
+
168
+ if (!user || !await bcrypt.compare(req.body.password, user.password)) {
169
+ return res.status(401).json({ error: 'Invalid credentials' }); // ✅ Generic
170
+ }
171
+ });
172
+ ```
173
+
174
+ ## Secure Logging
175
+
176
+ Log security events without exposing sensitive data.
177
+
178
+ ```typescript
179
+ // Bad - Logging sensitive data
180
+ logger.info('User login', {
181
+ email: user.email,
182
+ password: req.body.password, // ❌ Never log passwords
183
+ creditCard: user.creditCard // ❌ Never log PII
184
+ });
185
+
186
+ // Good - Log relevant info only
187
+ logger.info('User login', {
188
+ userId: user.id,
189
+ ip: req.ip,
190
+ userAgent: req.headers['user-agent'],
191
+ success: true
192
+ });
193
+
194
+ // Good - Mask sensitive data
195
+ const maskEmail = (email: string) => {
196
+ const [local, domain] = email.split('@');
197
+ return `${local.slice(0, 2)}***@${domain}`;
198
+ };
199
+
200
+ logger.info('Password reset requested', {
201
+ email: maskEmail(user.email),
202
+ ip: req.ip
203
+ });
204
+ ```
205
+
206
+ ## Dependency Security
207
+
208
+ Keep dependencies updated and secure.
209
+
210
+ ```bash
211
+ # Check for vulnerabilities
212
+ npm audit
213
+
214
+ # Fix vulnerabilities
215
+ npm audit fix
216
+
217
+ # Update dependencies
218
+ npm update
219
+
220
+ # Use lock files
221
+ npm ci # In CI/CD
222
+
223
+ # Monitor dependencies
224
+ # Use Dependabot, Snyk, or similar
225
+ ```
226
+
227
+ ## Environment Variables
228
+
229
+ Store secrets in environment variables.
230
+
231
+ ```typescript
232
+ // Bad - Hardcoded secrets
233
+ const dbPassword = 'mypassword123'; // ❌
234
+ const apiKey = 'sk_live_abc123'; // ❌
235
+
236
+ // Good - Environment variables
237
+ const dbPassword = process.env.DB_PASSWORD;
238
+ const apiKey = process.env.API_KEY;
239
+
240
+ // Good - Validate required env vars
241
+ const requiredEnvVars = ['DB_PASSWORD', 'API_KEY', 'JWT_SECRET'];
242
+
243
+ for (const envVar of requiredEnvVars) {
244
+ if (!process.env[envVar]) {
245
+ throw new Error(`Missing required environment variable: ${envVar}`);
246
+ }
247
+ }
248
+
249
+ // .env (never commit)
250
+ DB_PASSWORD=strong_password
251
+ API_KEY=sk_live_abc123
252
+ JWT_SECRET=random_secret
253
+
254
+ // .gitignore
255
+ .env
256
+ .env.local
257
+ .env.*.local
258
+ ```
259
+
260
+ ## Code Review
261
+
262
+ Implement security-focused code reviews.
263
+
264
+ ```markdown
265
+ # Security Review Checklist
266
+
267
+ - [ ] Input validation on all user input
268
+ - [ ] Authentication required for protected endpoints
269
+ - [ ] Authorization checks for resource access
270
+ - [ ] Parameterized queries (no SQL injection)
271
+ - [ ] No hardcoded secrets
272
+ - [ ] Sensitive data encrypted
273
+ - [ ] Error messages don't leak information
274
+ - [ ] Rate limiting on sensitive endpoints
275
+ - [ ] HTTPS enforced
276
+ - [ ] Security headers set
277
+ - [ ] Dependencies up to date
278
+ - [ ] Logging doesn't expose sensitive data
279
+ ```
280
+
281
+ ## Best Practices
282
+
283
+ 1. **Least privilege** - Minimum necessary permissions
284
+ 2. **Defense in depth** - Multiple security layers
285
+ 3. **Secure defaults** - Secure by default
286
+ 4. **Fail securely** - Don't expose internals
287
+ 5. **Validate server-side** - Never trust client
288
+ 6. **Generic errors** - Don't leak information
289
+ 7. **Secure logging** - Mask sensitive data
290
+ 8. **Update dependencies** - Patch vulnerabilities
291
+ 9. **Use env vars** - No hardcoded secrets
292
+ 10. **Code review** - Security-focused reviews
293
+