beth-copilot 1.0.0
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/README.md +224 -0
- package/bin/cli.js +223 -0
- package/package.json +36 -0
- package/templates/.github/agents/beth.agent.md +279 -0
- package/templates/.github/agents/developer.agent.md +493 -0
- package/templates/.github/agents/frontend-engineer.agent.md +556 -0
- package/templates/.github/agents/product-manager.agent.md +253 -0
- package/templates/.github/agents/researcher.agent.md +319 -0
- package/templates/.github/agents/security-reviewer.agent.md +452 -0
- package/templates/.github/agents/tester.agent.md +477 -0
- package/templates/.github/agents/ux-designer.agent.md +374 -0
- package/templates/.github/copilot-instructions.md +191 -0
- package/templates/.github/skills/framer-components/SKILL.md +564 -0
- package/templates/.github/skills/prd/SKILL.md +244 -0
- package/templates/.github/skills/security-analysis/SKILL.md +799 -0
- package/templates/.github/skills/shadcn-ui/SKILL.md +562 -0
- package/templates/.github/skills/vercel-react-best-practices/AGENTS.md +2516 -0
- package/templates/.github/skills/vercel-react-best-practices/SKILL.md +125 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/advanced-use-latest.md +49 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/async-dependencies.md +36 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +57 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/templates/.github/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/templates/.github/skills/web-design-guidelines/SKILL.md +39 -0
- package/templates/AGENTS.md +70 -0
- package/templates/Backlog.md +80 -0
- package/templates/mcp.json.example +9 -0
|
@@ -0,0 +1,799 @@
|
|
|
1
|
+
````skill
|
|
2
|
+
---
|
|
3
|
+
name: security-analysis
|
|
4
|
+
description: 'Enterprise security analysis using Azure Well-Architected Framework and OWASP standards. Use for security audits, threat modeling, vulnerability assessment, compliance verification, and secure code review. Triggers on: security review, security audit, threat model, vulnerability scan, OWASP, penetration test, compliance check, secure code review, WAF security.'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Enterprise Security Analysis Skill
|
|
8
|
+
|
|
9
|
+
Comprehensive security analysis framework combining Azure Well-Architected Framework Security Pillar and OWASP standards for enterprise-grade application security.
|
|
10
|
+
|
|
11
|
+
## When to Use This Skill
|
|
12
|
+
|
|
13
|
+
- User asks for "security review", "security audit", or "penetration test"
|
|
14
|
+
- User mentions "OWASP", "threat model", or "vulnerability"
|
|
15
|
+
- User wants "compliance check" or "secure code review"
|
|
16
|
+
- User asks about "authentication", "authorization", or "encryption"
|
|
17
|
+
- User mentions "Azure security", "WAF security", or "Zero Trust"
|
|
18
|
+
|
|
19
|
+
## The Job
|
|
20
|
+
|
|
21
|
+
1. Identify the scope and applicable standards
|
|
22
|
+
2. Perform systematic security analysis
|
|
23
|
+
3. Document findings with severity ratings
|
|
24
|
+
4. Provide actionable remediation guidance
|
|
25
|
+
5. Generate compliance verification checklist
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Azure Well-Architected Framework: Security Pillar
|
|
30
|
+
|
|
31
|
+
The Security pillar ensures confidentiality, integrity, and availability (CIA triad) through Zero Trust principles.
|
|
32
|
+
|
|
33
|
+
### Zero Trust Principles
|
|
34
|
+
|
|
35
|
+
| Principle | Implementation |
|
|
36
|
+
|-----------|---------------|
|
|
37
|
+
| **Verify explicitly** | Always authenticate and authorize based on all available data points |
|
|
38
|
+
| **Least privilege** | Limit access with Just-In-Time (JIT) and Just-Enough-Access (JEA) |
|
|
39
|
+
| **Assume breach** | Minimize blast radius, segment access, verify end-to-end encryption |
|
|
40
|
+
|
|
41
|
+
### Security Design Checklist (SE:01 - SE:12)
|
|
42
|
+
|
|
43
|
+
#### SE:01: Security Baseline
|
|
44
|
+
Establish a security baseline aligned with compliance requirements, industry standards, and platform recommendations.
|
|
45
|
+
|
|
46
|
+
**What to verify:**
|
|
47
|
+
- [ ] Security baseline documented
|
|
48
|
+
- [ ] Compliance requirements identified (SOC2, HIPAA, GDPR, PCI-DSS)
|
|
49
|
+
- [ ] Regular baseline reviews scheduled
|
|
50
|
+
- [ ] Deviations tracked and justified
|
|
51
|
+
|
|
52
|
+
**React/Next.js considerations:**
|
|
53
|
+
- Document security requirements in README
|
|
54
|
+
- Use security-focused ESLint rules
|
|
55
|
+
- Configure CSP headers in middleware
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
#### SE:02: Secure Development Lifecycle
|
|
60
|
+
Maintain a secure development lifecycle with hardened, automated, and auditable software supply chain.
|
|
61
|
+
|
|
62
|
+
**What to verify:**
|
|
63
|
+
- [ ] Threat modeling performed for new features
|
|
64
|
+
- [ ] Security requirements in user stories
|
|
65
|
+
- [ ] Code review includes security checks
|
|
66
|
+
- [ ] Dependency scanning enabled
|
|
67
|
+
- [ ] SAST/DAST tools integrated
|
|
68
|
+
|
|
69
|
+
**Implementation:**
|
|
70
|
+
```typescript
|
|
71
|
+
// package.json - Security-focused scripts
|
|
72
|
+
{
|
|
73
|
+
"scripts": {
|
|
74
|
+
"security:audit": "npm audit --audit-level=high",
|
|
75
|
+
"security:deps": "npx depcheck && npx npm-check-updates",
|
|
76
|
+
"lint:security": "eslint --plugin security ."
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
#### SE:03: Data Classification
|
|
84
|
+
Classify and consistently apply sensitivity labels on all workload data.
|
|
85
|
+
|
|
86
|
+
**Classification levels:**
|
|
87
|
+
| Level | Examples | Protection |
|
|
88
|
+
|-------|----------|------------|
|
|
89
|
+
| **Public** | Marketing content | Integrity protection |
|
|
90
|
+
| **Internal** | Documentation | Access control |
|
|
91
|
+
| **Confidential** | User emails, names | Encryption + access control |
|
|
92
|
+
| **Restricted** | Passwords, PII, financial | Strong encryption + audit + strict access |
|
|
93
|
+
|
|
94
|
+
**What to verify:**
|
|
95
|
+
- [ ] Data inventory maintained
|
|
96
|
+
- [ ] Classification labels applied
|
|
97
|
+
- [ ] Handling procedures documented
|
|
98
|
+
- [ ] Retention policies defined
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
#### SE:04: Segmentation
|
|
103
|
+
Create intentional segmentation and perimeters in architecture design.
|
|
104
|
+
|
|
105
|
+
**What to verify:**
|
|
106
|
+
- [ ] Network segmentation implemented
|
|
107
|
+
- [ ] Role-based access boundaries defined
|
|
108
|
+
- [ ] Service isolation configured
|
|
109
|
+
- [ ] Workload identity separation
|
|
110
|
+
|
|
111
|
+
**Next.js patterns:**
|
|
112
|
+
```typescript
|
|
113
|
+
// Segment by route group permissions
|
|
114
|
+
// app/(public)/ - No auth required
|
|
115
|
+
// app/(authenticated)/ - Login required
|
|
116
|
+
// app/(admin)/ - Admin role required
|
|
117
|
+
|
|
118
|
+
// middleware.ts
|
|
119
|
+
import { auth } from '@/lib/auth';
|
|
120
|
+
|
|
121
|
+
export async function middleware(request: NextRequest) {
|
|
122
|
+
const session = await auth();
|
|
123
|
+
const isAdminRoute = request.nextUrl.pathname.startsWith('/admin');
|
|
124
|
+
|
|
125
|
+
if (isAdminRoute && session?.user?.role !== 'admin') {
|
|
126
|
+
return NextResponse.redirect(new URL('/unauthorized', request.url));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const config = {
|
|
131
|
+
matcher: ['/admin/:path*', '/dashboard/:path*'],
|
|
132
|
+
};
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
#### SE:05: Identity and Access Management
|
|
138
|
+
Implement strict, conditional, and auditable IAM across all workload users and components.
|
|
139
|
+
|
|
140
|
+
**What to verify:**
|
|
141
|
+
- [ ] Authentication required for protected resources
|
|
142
|
+
- [ ] Authorization checked at every access point
|
|
143
|
+
- [ ] MFA enabled for sensitive operations
|
|
144
|
+
- [ ] Session management secure
|
|
145
|
+
- [ ] Service accounts use managed identities
|
|
146
|
+
|
|
147
|
+
**Secure authentication pattern:**
|
|
148
|
+
```typescript
|
|
149
|
+
// lib/auth.ts
|
|
150
|
+
import NextAuth from 'next-auth';
|
|
151
|
+
import { PrismaAdapter } from '@auth/prisma-adapter';
|
|
152
|
+
|
|
153
|
+
export const { handlers, auth, signIn, signOut } = NextAuth({
|
|
154
|
+
adapter: PrismaAdapter(prisma),
|
|
155
|
+
session: {
|
|
156
|
+
strategy: 'jwt',
|
|
157
|
+
maxAge: 24 * 60 * 60, // 24 hours
|
|
158
|
+
},
|
|
159
|
+
callbacks: {
|
|
160
|
+
async jwt({ token, user }) {
|
|
161
|
+
if (user) {
|
|
162
|
+
token.role = user.role;
|
|
163
|
+
token.permissions = user.permissions;
|
|
164
|
+
}
|
|
165
|
+
return token;
|
|
166
|
+
},
|
|
167
|
+
async session({ session, token }) {
|
|
168
|
+
session.user.role = token.role;
|
|
169
|
+
session.user.permissions = token.permissions;
|
|
170
|
+
return session;
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Authorization pattern:**
|
|
177
|
+
```typescript
|
|
178
|
+
// lib/auth/permissions.ts
|
|
179
|
+
export function canAccess(
|
|
180
|
+
user: User | null,
|
|
181
|
+
resource: string,
|
|
182
|
+
action: 'read' | 'write' | 'delete'
|
|
183
|
+
): boolean {
|
|
184
|
+
if (!user) return false;
|
|
185
|
+
|
|
186
|
+
const permissions = {
|
|
187
|
+
admin: ['read', 'write', 'delete'],
|
|
188
|
+
editor: ['read', 'write'],
|
|
189
|
+
viewer: ['read'],
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
return permissions[user.role]?.includes(action) ?? false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Usage in Server Action
|
|
196
|
+
'use server';
|
|
197
|
+
|
|
198
|
+
export async function updatePost(postId: string, data: FormData) {
|
|
199
|
+
const session = await auth();
|
|
200
|
+
|
|
201
|
+
if (!canAccess(session?.user, 'posts', 'write')) {
|
|
202
|
+
throw new Error('Forbidden');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Proceed with update...
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
#### SE:06: Network Security
|
|
212
|
+
Isolate, filter, and control network traffic across ingress and egress flows.
|
|
213
|
+
|
|
214
|
+
**What to verify:**
|
|
215
|
+
- [ ] HTTPS enforced everywhere
|
|
216
|
+
- [ ] API endpoints protected
|
|
217
|
+
- [ ] CORS properly configured
|
|
218
|
+
- [ ] Rate limiting implemented
|
|
219
|
+
- [ ] DDoS protection enabled
|
|
220
|
+
|
|
221
|
+
**Next.js security headers:**
|
|
222
|
+
```typescript
|
|
223
|
+
// next.config.js
|
|
224
|
+
const securityHeaders = [
|
|
225
|
+
{
|
|
226
|
+
key: 'Strict-Transport-Security',
|
|
227
|
+
value: 'max-age=63072000; includeSubDomains; preload',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
key: 'X-Content-Type-Options',
|
|
231
|
+
value: 'nosniff',
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
key: 'X-Frame-Options',
|
|
235
|
+
value: 'DENY',
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
key: 'X-XSS-Protection',
|
|
239
|
+
value: '1; mode=block',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
key: 'Referrer-Policy',
|
|
243
|
+
value: 'strict-origin-when-cross-origin',
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
key: 'Content-Security-Policy',
|
|
247
|
+
value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';",
|
|
248
|
+
},
|
|
249
|
+
];
|
|
250
|
+
|
|
251
|
+
module.exports = {
|
|
252
|
+
async headers() {
|
|
253
|
+
return [{ source: '/:path*', headers: securityHeaders }];
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Rate limiting:**
|
|
259
|
+
```typescript
|
|
260
|
+
// lib/rate-limit.ts
|
|
261
|
+
import { Ratelimit } from '@upstash/ratelimit';
|
|
262
|
+
import { Redis } from '@upstash/redis';
|
|
263
|
+
|
|
264
|
+
const ratelimit = new Ratelimit({
|
|
265
|
+
redis: Redis.fromEnv(),
|
|
266
|
+
limiter: Ratelimit.slidingWindow(10, '10 s'),
|
|
267
|
+
analytics: true,
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
export async function checkRateLimit(identifier: string) {
|
|
271
|
+
const { success, limit, remaining, reset } = await ratelimit.limit(identifier);
|
|
272
|
+
return { allowed: success, limit, remaining, retryAfter: Math.ceil((reset - Date.now()) / 1000) };
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
#### SE:07: Encryption
|
|
279
|
+
Encrypt data using modern, industry-standard methods.
|
|
280
|
+
|
|
281
|
+
**What to verify:**
|
|
282
|
+
- [ ] TLS 1.2+ for all connections
|
|
283
|
+
- [ ] Database encryption at rest
|
|
284
|
+
- [ ] Sensitive fields encrypted (PII, credentials)
|
|
285
|
+
- [ ] Key rotation policy defined
|
|
286
|
+
- [ ] No secrets in client code
|
|
287
|
+
|
|
288
|
+
**Encryption patterns:**
|
|
289
|
+
```typescript
|
|
290
|
+
// lib/crypto.ts
|
|
291
|
+
import { createCipheriv, createDecipheriv, randomBytes, scrypt } from 'crypto';
|
|
292
|
+
import { promisify } from 'util';
|
|
293
|
+
|
|
294
|
+
const scryptAsync = promisify(scrypt);
|
|
295
|
+
const ALGORITHM = 'aes-256-gcm';
|
|
296
|
+
|
|
297
|
+
export async function encrypt(text: string): Promise<string> {
|
|
298
|
+
const key = await scryptAsync(process.env.ENCRYPTION_KEY!, 'salt', 32) as Buffer;
|
|
299
|
+
const iv = randomBytes(16);
|
|
300
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
301
|
+
|
|
302
|
+
let encrypted = cipher.update(text, 'utf8', 'hex');
|
|
303
|
+
encrypted += cipher.final('hex');
|
|
304
|
+
|
|
305
|
+
const authTag = cipher.getAuthTag();
|
|
306
|
+
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export async function decrypt(encryptedText: string): Promise<string> {
|
|
310
|
+
const [ivHex, authTagHex, encrypted] = encryptedText.split(':');
|
|
311
|
+
const key = await scryptAsync(process.env.ENCRYPTION_KEY!, 'salt', 32) as Buffer;
|
|
312
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
313
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
314
|
+
|
|
315
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
316
|
+
decipher.setAuthTag(authTag);
|
|
317
|
+
|
|
318
|
+
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
319
|
+
decrypted += decipher.final('utf8');
|
|
320
|
+
return decrypted;
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
#### SE:08: Resource Hardening
|
|
327
|
+
Harden all workload components by reducing attack surface.
|
|
328
|
+
|
|
329
|
+
**What to verify:**
|
|
330
|
+
- [ ] Unused features disabled
|
|
331
|
+
- [ ] Default credentials changed
|
|
332
|
+
- [ ] Debug mode disabled in production
|
|
333
|
+
- [ ] Error messages don't leak information
|
|
334
|
+
- [ ] Dependencies minimized
|
|
335
|
+
|
|
336
|
+
**Production hardening:**
|
|
337
|
+
```typescript
|
|
338
|
+
// app/api/[...]/route.ts
|
|
339
|
+
export async function GET(request: Request) {
|
|
340
|
+
try {
|
|
341
|
+
// Business logic...
|
|
342
|
+
} catch (error) {
|
|
343
|
+
// Log full error server-side
|
|
344
|
+
console.error('API Error:', error);
|
|
345
|
+
|
|
346
|
+
// Return generic message to client
|
|
347
|
+
return NextResponse.json(
|
|
348
|
+
{ error: 'An error occurred' },
|
|
349
|
+
{ status: 500 }
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// next.config.js
|
|
355
|
+
module.exports = {
|
|
356
|
+
productionBrowserSourceMaps: false,
|
|
357
|
+
poweredByHeader: false,
|
|
358
|
+
};
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
#### SE:09: Secret Management
|
|
364
|
+
Protect application secrets by hardening storage and restricting access.
|
|
365
|
+
|
|
366
|
+
**What to verify:**
|
|
367
|
+
- [ ] Secrets in environment variables (never in code)
|
|
368
|
+
- [ ] Different secrets per environment
|
|
369
|
+
- [ ] Secret rotation automated
|
|
370
|
+
- [ ] Access audited
|
|
371
|
+
- [ ] No secrets in client-side code
|
|
372
|
+
|
|
373
|
+
**Secret management patterns:**
|
|
374
|
+
```typescript
|
|
375
|
+
// ❌ NEVER do this
|
|
376
|
+
const API_KEY = 'sk_live_123...'; // Hardcoded
|
|
377
|
+
export const secret = process.env.NEXT_PUBLIC_SECRET; // Client-exposed
|
|
378
|
+
|
|
379
|
+
// ✅ Correct patterns
|
|
380
|
+
// .env.local (never committed)
|
|
381
|
+
DATABASE_URL="postgresql://user:pass@host/db"
|
|
382
|
+
API_SECRET="sk_live_..."
|
|
383
|
+
|
|
384
|
+
// Validate at startup
|
|
385
|
+
const requiredEnvVars = ['DATABASE_URL', 'API_SECRET', 'NEXTAUTH_SECRET'];
|
|
386
|
+
|
|
387
|
+
for (const envVar of requiredEnvVars) {
|
|
388
|
+
if (!process.env[envVar]) {
|
|
389
|
+
throw new Error(`Missing required environment variable: ${envVar}`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
#### SE:10: Threat Detection & Monitoring
|
|
397
|
+
Implement holistic monitoring with modern threat detection.
|
|
398
|
+
|
|
399
|
+
**What to verify:**
|
|
400
|
+
- [ ] Security events logged
|
|
401
|
+
- [ ] Alerting configured
|
|
402
|
+
- [ ] Log retention policy defined
|
|
403
|
+
- [ ] Anomaly detection enabled
|
|
404
|
+
- [ ] Incident correlation possible
|
|
405
|
+
|
|
406
|
+
**Audit logging pattern:**
|
|
407
|
+
```typescript
|
|
408
|
+
// lib/audit.ts
|
|
409
|
+
type AuditEvent = {
|
|
410
|
+
action: string;
|
|
411
|
+
actor: string;
|
|
412
|
+
resource: string;
|
|
413
|
+
resourceId?: string;
|
|
414
|
+
outcome: 'success' | 'failure';
|
|
415
|
+
metadata?: Record<string, unknown>;
|
|
416
|
+
ip?: string;
|
|
417
|
+
userAgent?: string;
|
|
418
|
+
timestamp: Date;
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
export async function auditLog(event: AuditEvent) {
|
|
422
|
+
await db.auditLog.create({
|
|
423
|
+
data: {
|
|
424
|
+
...event,
|
|
425
|
+
timestamp: new Date(),
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// For critical events, also send to SIEM
|
|
430
|
+
if (event.action.startsWith('auth.') || event.outcome === 'failure') {
|
|
431
|
+
await sendToSIEM(event);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Usage
|
|
436
|
+
await auditLog({
|
|
437
|
+
action: 'user.delete',
|
|
438
|
+
actor: session.user.id,
|
|
439
|
+
resource: 'user',
|
|
440
|
+
resourceId: targetUserId,
|
|
441
|
+
outcome: 'success',
|
|
442
|
+
ip: request.headers.get('x-forwarded-for'),
|
|
443
|
+
});
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
#### SE:11: Security Testing
|
|
449
|
+
Establish comprehensive testing regimen combining multiple approaches.
|
|
450
|
+
|
|
451
|
+
**What to verify:**
|
|
452
|
+
- [ ] SAST integrated in CI/CD
|
|
453
|
+
- [ ] DAST scheduled regularly
|
|
454
|
+
- [ ] Penetration testing annual
|
|
455
|
+
- [ ] Dependency scanning automated
|
|
456
|
+
- [ ] Security unit tests exist
|
|
457
|
+
|
|
458
|
+
**Security testing setup:**
|
|
459
|
+
```typescript
|
|
460
|
+
// vitest.config.ts - Include security tests
|
|
461
|
+
export default defineConfig({
|
|
462
|
+
test: {
|
|
463
|
+
include: ['**/*.test.ts', '**/*.security.test.ts'],
|
|
464
|
+
},
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// auth.security.test.ts
|
|
468
|
+
describe('Authentication Security', () => {
|
|
469
|
+
it('rejects requests without valid session', async () => {
|
|
470
|
+
const response = await fetch('/api/admin/users');
|
|
471
|
+
expect(response.status).toBe(401);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it('prevents IDOR attacks', async () => {
|
|
475
|
+
// Login as user A
|
|
476
|
+
const sessionA = await loginAs('userA');
|
|
477
|
+
|
|
478
|
+
// Try to access user B's data
|
|
479
|
+
const response = await fetch('/api/users/userB/profile', {
|
|
480
|
+
headers: { Authorization: `Bearer ${sessionA.token}` },
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
expect(response.status).toBe(403);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('rate limits failed login attempts', async () => {
|
|
487
|
+
for (let i = 0; i < 10; i++) {
|
|
488
|
+
await fetch('/api/auth/login', {
|
|
489
|
+
method: 'POST',
|
|
490
|
+
body: JSON.stringify({ email: 'test@test.com', password: 'wrong' }),
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const response = await fetch('/api/auth/login', {
|
|
495
|
+
method: 'POST',
|
|
496
|
+
body: JSON.stringify({ email: 'test@test.com', password: 'wrong' }),
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
expect(response.status).toBe(429);
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
#### SE:12: Incident Response
|
|
507
|
+
Define and test effective incident response procedures.
|
|
508
|
+
|
|
509
|
+
**What to verify:**
|
|
510
|
+
- [ ] Incident response plan documented
|
|
511
|
+
- [ ] Roles and responsibilities defined
|
|
512
|
+
- [ ] Communication channels established
|
|
513
|
+
- [ ] Recovery procedures tested
|
|
514
|
+
- [ ] Post-incident review process
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## OWASP Top 10:2025
|
|
519
|
+
|
|
520
|
+
### A01: Broken Access Control
|
|
521
|
+
|
|
522
|
+
**What it is:** Failures in enforcing policies where users should only act within their intended permissions.
|
|
523
|
+
|
|
524
|
+
**What to check:**
|
|
525
|
+
- [ ] Authorization checked on every request
|
|
526
|
+
- [ ] No direct object references exposed
|
|
527
|
+
- [ ] URL manipulation prevented
|
|
528
|
+
- [ ] CORS properly configured
|
|
529
|
+
- [ ] Token validation on all protected routes
|
|
530
|
+
|
|
531
|
+
**Vulnerable pattern:**
|
|
532
|
+
```typescript
|
|
533
|
+
// ❌ Vulnerable: No authorization check
|
|
534
|
+
export async function getOrder(orderId: string) {
|
|
535
|
+
return db.order.findUnique({ where: { id: orderId } });
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// ✅ Secure: Verify ownership
|
|
539
|
+
export async function getOrder(orderId: string, userId: string) {
|
|
540
|
+
const order = await db.order.findUnique({
|
|
541
|
+
where: { id: orderId, userId } // Ensure user owns this order
|
|
542
|
+
});
|
|
543
|
+
if (!order) throw new Error('Order not found');
|
|
544
|
+
return order;
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
### A02: Security Misconfiguration
|
|
551
|
+
|
|
552
|
+
**What it is:** Missing security hardening, unnecessary features enabled, default credentials.
|
|
553
|
+
|
|
554
|
+
**What to check:**
|
|
555
|
+
- [ ] Security headers configured
|
|
556
|
+
- [ ] Debug mode disabled in production
|
|
557
|
+
- [ ] Default accounts/passwords changed
|
|
558
|
+
- [ ] Error messages don't leak info
|
|
559
|
+
- [ ] Unnecessary features disabled
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
### A03: Software Supply Chain Failures
|
|
564
|
+
|
|
565
|
+
**What it is:** Vulnerabilities from third-party dependencies or compromised CI/CD pipelines.
|
|
566
|
+
|
|
567
|
+
**What to check:**
|
|
568
|
+
- [ ] All dependencies audited (`npm audit`)
|
|
569
|
+
- [ ] Lock file committed
|
|
570
|
+
- [ ] Dependency updates automated
|
|
571
|
+
- [ ] Build integrity verified
|
|
572
|
+
- [ ] Signed commits (optional but recommended)
|
|
573
|
+
|
|
574
|
+
**Setup:**
|
|
575
|
+
```bash
|
|
576
|
+
# .github/workflows/security.yml
|
|
577
|
+
name: Security Scan
|
|
578
|
+
on: [push, pull_request]
|
|
579
|
+
jobs:
|
|
580
|
+
audit:
|
|
581
|
+
runs-on: ubuntu-latest
|
|
582
|
+
steps:
|
|
583
|
+
- uses: actions/checkout@v4
|
|
584
|
+
- run: npm ci
|
|
585
|
+
- run: npm audit --audit-level=high
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
### A04: Cryptographic Failures
|
|
591
|
+
|
|
592
|
+
**What it is:** Failures in protecting data in transit or at rest through proper cryptography.
|
|
593
|
+
|
|
594
|
+
**What to check:**
|
|
595
|
+
- [ ] TLS 1.2+ enforced
|
|
596
|
+
- [ ] Passwords properly hashed (bcrypt, argon2)
|
|
597
|
+
- [ ] Sensitive data encrypted at rest
|
|
598
|
+
- [ ] No weak algorithms (MD5, SHA1)
|
|
599
|
+
- [ ] Keys properly managed
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
### A05: Injection
|
|
604
|
+
|
|
605
|
+
**What it is:** Hostile data sent to interpreters (SQL, NoSQL, OS, LDAP).
|
|
606
|
+
|
|
607
|
+
**What to check:**
|
|
608
|
+
- [ ] All input validated with schemas
|
|
609
|
+
- [ ] Parameterized queries used
|
|
610
|
+
- [ ] Output encoded for context
|
|
611
|
+
- [ ] No dynamic query construction
|
|
612
|
+
|
|
613
|
+
**Prevention:**
|
|
614
|
+
```typescript
|
|
615
|
+
// ❌ Vulnerable: String interpolation
|
|
616
|
+
const users = await db.$queryRaw`SELECT * FROM users WHERE name = '${name}'`;
|
|
617
|
+
|
|
618
|
+
// ✅ Secure: Parameterized query
|
|
619
|
+
const users = await db.$queryRaw`SELECT * FROM users WHERE name = ${name}`;
|
|
620
|
+
|
|
621
|
+
// ✅ Better: Use ORM with validation
|
|
622
|
+
const nameSchema = z.string().min(1).max(100);
|
|
623
|
+
const parsed = nameSchema.parse(name);
|
|
624
|
+
const users = await db.user.findMany({ where: { name: parsed } });
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
629
|
+
### A06: Insecure Design
|
|
630
|
+
|
|
631
|
+
**What it is:** Missing or ineffective security controls and patterns in design.
|
|
632
|
+
|
|
633
|
+
**What to check:**
|
|
634
|
+
- [ ] Threat modeling performed
|
|
635
|
+
- [ ] Security requirements defined
|
|
636
|
+
- [ ] Defense in depth implemented
|
|
637
|
+
- [ ] Fail-safe defaults configured
|
|
638
|
+
- [ ] Least privilege enforced
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
### A07: Authentication Failures
|
|
643
|
+
|
|
644
|
+
**What it is:** Confirmation of user identity, authentication, and session management weaknesses.
|
|
645
|
+
|
|
646
|
+
**What to check:**
|
|
647
|
+
- [ ] Credential stuffing protection
|
|
648
|
+
- [ ] Brute force protection
|
|
649
|
+
- [ ] Session fixation prevention
|
|
650
|
+
- [ ] Secure password storage
|
|
651
|
+
- [ ] MFA available
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
### A08: Software or Data Integrity Failures
|
|
656
|
+
|
|
657
|
+
**What it is:** Code and infrastructure that doesn't protect against integrity violations.
|
|
658
|
+
|
|
659
|
+
**What to check:**
|
|
660
|
+
- [ ] CI/CD pipeline secured
|
|
661
|
+
- [ ] Updates from verified sources
|
|
662
|
+
- [ ] Serialized data validated
|
|
663
|
+
- [ ] Dependencies verified
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
667
|
+
### A09: Security Logging and Alerting Failures
|
|
668
|
+
|
|
669
|
+
**What it is:** Insufficient logging, detection, monitoring, and response.
|
|
670
|
+
|
|
671
|
+
**What to check:**
|
|
672
|
+
- [ ] Login attempts logged
|
|
673
|
+
- [ ] Access control failures logged
|
|
674
|
+
- [ ] Input validation failures logged
|
|
675
|
+
- [ ] Alerts configured for anomalies
|
|
676
|
+
- [ ] Logs tamper-proof
|
|
677
|
+
|
|
678
|
+
---
|
|
679
|
+
|
|
680
|
+
### A10: Mishandling of Exceptional Conditions
|
|
681
|
+
|
|
682
|
+
**What it is:** Server-side request forgery allowing attackers to send crafted requests.
|
|
683
|
+
|
|
684
|
+
**What to check:**
|
|
685
|
+
- [ ] URL validation for user input
|
|
686
|
+
- [ ] Allow-list for external requests
|
|
687
|
+
- [ ] Split DNS prevented
|
|
688
|
+
- [ ] Network segmentation
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
## Security Review Checklist
|
|
693
|
+
|
|
694
|
+
### Quick Review (15 min)
|
|
695
|
+
- [ ] Authentication on protected routes
|
|
696
|
+
- [ ] Authorization checks in Server Actions
|
|
697
|
+
- [ ] Input validation with Zod
|
|
698
|
+
- [ ] No secrets in client code
|
|
699
|
+
- [ ] Security headers configured
|
|
700
|
+
|
|
701
|
+
### Standard Review (1-2 hours)
|
|
702
|
+
All of quick review, plus:
|
|
703
|
+
- [ ] OWASP Top 10 categories assessed
|
|
704
|
+
- [ ] Session management reviewed
|
|
705
|
+
- [ ] Error handling verified
|
|
706
|
+
- [ ] Audit logging present
|
|
707
|
+
- [ ] Dependencies audited
|
|
708
|
+
|
|
709
|
+
### Comprehensive Audit (1+ days)
|
|
710
|
+
All of standard review, plus:
|
|
711
|
+
- [ ] Full WAF SE:01-SE:12 checklist
|
|
712
|
+
- [ ] Threat model created/updated
|
|
713
|
+
- [ ] Penetration testing
|
|
714
|
+
- [ ] Compliance verification
|
|
715
|
+
- [ ] Architecture security review
|
|
716
|
+
|
|
717
|
+
## Severity Ratings
|
|
718
|
+
|
|
719
|
+
| Rating | Description | SLA |
|
|
720
|
+
|--------|-------------|-----|
|
|
721
|
+
| **Critical** | Actively exploitable, data breach risk | Fix immediately |
|
|
722
|
+
| **High** | Significant vulnerability, exploitation possible | 24-48 hours |
|
|
723
|
+
| **Medium** | Moderate risk, requires conditions | 1 week |
|
|
724
|
+
| **Low** | Minor issue, defense in depth | Next release |
|
|
725
|
+
| **Informational** | Best practice recommendation | Backlog |
|
|
726
|
+
|
|
727
|
+
## Report Template
|
|
728
|
+
|
|
729
|
+
```markdown
|
|
730
|
+
# Security Assessment Report
|
|
731
|
+
|
|
732
|
+
**Target:** [Application/Component]
|
|
733
|
+
**Date:** [Date]
|
|
734
|
+
**Assessor:** Security Reviewer Agent
|
|
735
|
+
**Classification:** [Confidential/Internal]
|
|
736
|
+
|
|
737
|
+
## Executive Summary
|
|
738
|
+
|
|
739
|
+
Overall risk level: [Critical/High/Medium/Low]
|
|
740
|
+
|
|
741
|
+
| Severity | Count |
|
|
742
|
+
|----------|-------|
|
|
743
|
+
| Critical | X |
|
|
744
|
+
| High | X |
|
|
745
|
+
| Medium | X |
|
|
746
|
+
| Low | X |
|
|
747
|
+
|
|
748
|
+
## Findings
|
|
749
|
+
|
|
750
|
+
### [CRITICAL-001] Finding Title
|
|
751
|
+
**Category:** OWASP A0X / WAF SE:XX
|
|
752
|
+
**CVSS:** X.X
|
|
753
|
+
**Location:** [file:line]
|
|
754
|
+
|
|
755
|
+
**Description:**
|
|
756
|
+
[What the vulnerability is]
|
|
757
|
+
|
|
758
|
+
**Impact:**
|
|
759
|
+
[What could happen if exploited]
|
|
760
|
+
|
|
761
|
+
**Evidence:**
|
|
762
|
+
\`\`\`typescript
|
|
763
|
+
// Vulnerable code
|
|
764
|
+
\`\`\`
|
|
765
|
+
|
|
766
|
+
**Remediation:**
|
|
767
|
+
[How to fix it with code example]
|
|
768
|
+
|
|
769
|
+
**References:**
|
|
770
|
+
- [OWASP Link]
|
|
771
|
+
- [Azure WAF Link]
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
## Compliance Status
|
|
776
|
+
|
|
777
|
+
### Azure WAF Security Pillar
|
|
778
|
+
| Control | Status | Notes |
|
|
779
|
+
|---------|--------|-------|
|
|
780
|
+
| SE:01 Baseline | ✅/⚠️/❌ | |
|
|
781
|
+
| SE:02 SDL | ✅/⚠️/❌ | |
|
|
782
|
+
...
|
|
783
|
+
|
|
784
|
+
### OWASP Top 10:2025
|
|
785
|
+
| Category | Status | Notes |
|
|
786
|
+
|----------|--------|-------|
|
|
787
|
+
| A01 Access Control | ✅/⚠️/❌ | |
|
|
788
|
+
| A02 Misconfiguration | ✅/⚠️/❌ | |
|
|
789
|
+
...
|
|
790
|
+
|
|
791
|
+
## Recommendations
|
|
792
|
+
|
|
793
|
+
1. **Immediate:** [Critical fixes]
|
|
794
|
+
2. **Short-term:** [High priority items]
|
|
795
|
+
3. **Medium-term:** [Medium priority items]
|
|
796
|
+
4. **Long-term:** [Architecture improvements]
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
````
|