omgkit 2.2.0 → 2.3.1
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 +3 -3
- package/package.json +1 -1
- package/plugin/skills/databases/database-management/SKILL.md +288 -0
- package/plugin/skills/databases/database-migration/SKILL.md +285 -0
- package/plugin/skills/databases/database-schema-design/SKILL.md +195 -0
- package/plugin/skills/databases/mongodb/SKILL.md +60 -776
- package/plugin/skills/databases/prisma/SKILL.md +53 -744
- package/plugin/skills/databases/redis/SKILL.md +53 -860
- package/plugin/skills/databases/supabase/SKILL.md +283 -0
- package/plugin/skills/devops/aws/SKILL.md +68 -672
- package/plugin/skills/devops/github-actions/SKILL.md +54 -657
- package/plugin/skills/devops/kubernetes/SKILL.md +67 -602
- package/plugin/skills/devops/performance-profiling/SKILL.md +59 -863
- package/plugin/skills/frameworks/django/SKILL.md +87 -853
- package/plugin/skills/frameworks/express/SKILL.md +95 -1301
- package/plugin/skills/frameworks/fastapi/SKILL.md +90 -1198
- package/plugin/skills/frameworks/laravel/SKILL.md +87 -1187
- package/plugin/skills/frameworks/nestjs/SKILL.md +106 -973
- package/plugin/skills/frameworks/react/SKILL.md +94 -962
- package/plugin/skills/frameworks/vue/SKILL.md +95 -1242
- package/plugin/skills/frontend/accessibility/SKILL.md +91 -1056
- package/plugin/skills/frontend/frontend-design/SKILL.md +69 -1262
- package/plugin/skills/frontend/responsive/SKILL.md +76 -799
- package/plugin/skills/frontend/shadcn-ui/SKILL.md +73 -921
- package/plugin/skills/frontend/tailwindcss/SKILL.md +60 -788
- package/plugin/skills/frontend/threejs/SKILL.md +72 -1266
- package/plugin/skills/languages/javascript/SKILL.md +106 -849
- package/plugin/skills/methodology/brainstorming/SKILL.md +70 -576
- package/plugin/skills/methodology/defense-in-depth/SKILL.md +79 -831
- package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +81 -654
- package/plugin/skills/methodology/executing-plans/SKILL.md +86 -529
- package/plugin/skills/methodology/finishing-development-branch/SKILL.md +95 -586
- package/plugin/skills/methodology/problem-solving/SKILL.md +67 -681
- package/plugin/skills/methodology/receiving-code-review/SKILL.md +70 -533
- package/plugin/skills/methodology/requesting-code-review/SKILL.md +70 -610
- package/plugin/skills/methodology/root-cause-tracing/SKILL.md +70 -646
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +70 -478
- package/plugin/skills/methodology/systematic-debugging/SKILL.md +66 -559
- package/plugin/skills/methodology/test-driven-development/SKILL.md +91 -752
- package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +78 -687
- package/plugin/skills/methodology/token-optimization/SKILL.md +72 -602
- package/plugin/skills/methodology/verification-before-completion/SKILL.md +108 -529
- package/plugin/skills/methodology/writing-plans/SKILL.md +79 -566
- package/plugin/skills/omega/omega-architecture/SKILL.md +91 -752
- package/plugin/skills/omega/omega-coding/SKILL.md +161 -552
- package/plugin/skills/omega/omega-sprint/SKILL.md +132 -777
- package/plugin/skills/omega/omega-testing/SKILL.md +157 -845
- package/plugin/skills/omega/omega-thinking/SKILL.md +165 -606
- package/plugin/skills/security/better-auth/SKILL.md +46 -1034
- package/plugin/skills/security/oauth/SKILL.md +80 -934
- package/plugin/skills/security/owasp/SKILL.md +78 -862
- package/plugin/skills/testing/playwright/SKILL.md +77 -700
- package/plugin/skills/testing/pytest/SKILL.md +73 -811
- package/plugin/skills/testing/vitest/SKILL.md +60 -920
- package/plugin/skills/tools/document-processing/SKILL.md +111 -838
- package/plugin/skills/tools/image-processing/SKILL.md +126 -659
- package/plugin/skills/tools/mcp-development/SKILL.md +85 -758
- package/plugin/skills/tools/media-processing/SKILL.md +118 -735
- package/plugin/stdrules/SKILL_STANDARDS.md +490 -0
- package/plugin/skills/SKILL_STANDARDS.md +0 -743
|
@@ -1,849 +1,97 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: defense-in-depth
|
|
3
|
-
description:
|
|
4
|
-
category: methodology
|
|
5
|
-
triggers:
|
|
6
|
-
- defense in depth
|
|
7
|
-
- security layers
|
|
8
|
-
- layered security
|
|
9
|
-
- security architecture
|
|
10
|
-
- multiple barriers
|
|
11
|
-
- security controls
|
|
12
|
-
- protective layers
|
|
2
|
+
name: implementing-defense-in-depth
|
|
3
|
+
description: AI agent designs layered security architecture with multiple independent protective barriers ensuring no single point of failure. Use when building security systems, reviewing architecture, or hardening applications.
|
|
13
4
|
---
|
|
14
5
|
|
|
15
|
-
# Defense in Depth
|
|
6
|
+
# Implementing Defense in Depth
|
|
16
7
|
|
|
17
|
-
|
|
8
|
+
## Quick Start
|
|
18
9
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- Prevent single points of security failure
|
|
26
|
-
- Slow down attackers at every step
|
|
27
|
-
- Provide time to detect and respond to breaches
|
|
28
|
-
- Limit blast radius when breaches occur
|
|
29
|
-
- Maintain security even when some controls fail
|
|
10
|
+
1. **Perimeter** - WAF, DDoS protection, rate limiting, IP filtering
|
|
11
|
+
2. **Network** - VPC, security groups, mTLS, network policies
|
|
12
|
+
3. **Application** - Input validation, output encoding, CSRF, CSP
|
|
13
|
+
4. **Data** - Encryption at rest/transit, access control, classification
|
|
14
|
+
5. **Identity** - MFA, least privilege, session management
|
|
15
|
+
6. **Monitoring** - Logging, alerting, anomaly detection across all layers
|
|
30
16
|
|
|
31
17
|
## Features
|
|
32
18
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
│ │
|
|
42
|
-
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
|
43
|
-
│ │ LAYER 1: PERIMETER │ │
|
|
44
|
-
│ │ ════════════════════ │ │
|
|
45
|
-
│ │ WAF │ DDoS Protection │ Rate Limiting │ IP Filtering │ │
|
|
46
|
-
│ │ │ │
|
|
47
|
-
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
|
|
48
|
-
│ │ │ LAYER 2: NETWORK │ │ │
|
|
49
|
-
│ │ │ ═════════════════ │ │ │
|
|
50
|
-
│ │ │ VPC │ Security Groups │ Network Policies │ TLS Everywhere │ │ │
|
|
51
|
-
│ │ │ │ │ │
|
|
52
|
-
│ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │
|
|
53
|
-
│ │ │ │ LAYER 3: APPLICATION │ │ │ │
|
|
54
|
-
│ │ │ │ ═════════════════════ │ │ │ │
|
|
55
|
-
│ │ │ │ Input Validation │ Output Encoding │ CSRF │ CSP │ │ │ │
|
|
56
|
-
│ │ │ │ │ │ │ │
|
|
57
|
-
│ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │
|
|
58
|
-
│ │ │ │ │ LAYER 4: DATA │ │ │ │ │
|
|
59
|
-
│ │ │ │ │ ═══════════════ │ │ │ │ │
|
|
60
|
-
│ │ │ │ │ Encryption at Rest │ Encryption in Transit │ │ │ │ │
|
|
61
|
-
│ │ │ │ │ Access Control │ Data Classification │ │ │ │ │
|
|
62
|
-
│ │ │ │ │ │ │ │ │ │
|
|
63
|
-
│ │ │ │ │ ┌───────────────────────────────────────────┐ │ │ │ │ │
|
|
64
|
-
│ │ │ │ │ │ LAYER 5: IDENTITY │ │ │ │ │ │
|
|
65
|
-
│ │ │ │ │ │ ═══════════════════ │ │ │ │ │ │
|
|
66
|
-
│ │ │ │ │ │ MFA │ Least Privilege │ Session Mgmt │ │ │ │ │ │
|
|
67
|
-
│ │ │ │ │ └───────────────────────────────────────────┘ │ │ │ │ │
|
|
68
|
-
│ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │
|
|
69
|
-
│ │ │ └───────────────────────────────────────────────────────┘ │ │ │
|
|
70
|
-
│ │ └─────────────────────────────────────────────────────────────┘ │ │
|
|
71
|
-
│ └───────────────────────────────────────────────────────────────────┘ │
|
|
72
|
-
│ │
|
|
73
|
-
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
|
74
|
-
│ │ CROSS-CUTTING: MONITORING & DETECTION │ │
|
|
75
|
-
│ │ Logging │ Alerting │ Anomaly Detection │ Incident Response │ │
|
|
76
|
-
│ └───────────────────────────────────────────────────────────────────┘ │
|
|
77
|
-
│ │
|
|
78
|
-
└─────────────────────────────────────────────────────────────────────────┘
|
|
79
|
-
|
|
80
|
-
PRINCIPLE: If one layer fails, others still protect the asset.
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### 2. Layer 1: Perimeter Security
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
/**
|
|
87
|
-
* Perimeter Security: First line of defense
|
|
88
|
-
* Block attacks before they reach your application
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
// WAF (Web Application Firewall) Configuration
|
|
92
|
-
const wafConfig = {
|
|
93
|
-
rules: [
|
|
94
|
-
// SQL Injection patterns
|
|
95
|
-
{
|
|
96
|
-
name: 'sql-injection',
|
|
97
|
-
action: 'block',
|
|
98
|
-
patterns: [
|
|
99
|
-
/(\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER)\b)/i,
|
|
100
|
-
/(\b(OR|AND)\s+\d+\s*=\s*\d+)/i,
|
|
101
|
-
/(--|\#|\/\*)/
|
|
102
|
-
]
|
|
103
|
-
},
|
|
104
|
-
// XSS patterns
|
|
105
|
-
{
|
|
106
|
-
name: 'xss-attack',
|
|
107
|
-
action: 'block',
|
|
108
|
-
patterns: [
|
|
109
|
-
/<script\b[^>]*>/i,
|
|
110
|
-
/javascript:/i,
|
|
111
|
-
/on\w+\s*=/i
|
|
112
|
-
]
|
|
113
|
-
},
|
|
114
|
-
// Path traversal
|
|
115
|
-
{
|
|
116
|
-
name: 'path-traversal',
|
|
117
|
-
action: 'block',
|
|
118
|
-
patterns: [
|
|
119
|
-
/\.\.\//,
|
|
120
|
-
/\.\.\\/
|
|
121
|
-
]
|
|
122
|
-
}
|
|
123
|
-
]
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
// Rate Limiting Configuration
|
|
127
|
-
interface RateLimitConfig {
|
|
128
|
-
global: {
|
|
129
|
-
requestsPerSecond: number;
|
|
130
|
-
burstSize: number;
|
|
131
|
-
};
|
|
132
|
-
perEndpoint: Map<string, EndpointLimit>;
|
|
133
|
-
perUser: {
|
|
134
|
-
requestsPerMinute: number;
|
|
135
|
-
requestsPerHour: number;
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const rateLimiting: RateLimitConfig = {
|
|
140
|
-
global: {
|
|
141
|
-
requestsPerSecond: 10000,
|
|
142
|
-
burstSize: 15000
|
|
143
|
-
},
|
|
144
|
-
perEndpoint: new Map([
|
|
145
|
-
['/api/login', { requestsPerMinute: 5, lockoutDuration: 900 }],
|
|
146
|
-
['/api/register', { requestsPerMinute: 2, lockoutDuration: 3600 }],
|
|
147
|
-
['/api/password-reset', { requestsPerMinute: 3, lockoutDuration: 3600 }]
|
|
148
|
-
]),
|
|
149
|
-
perUser: {
|
|
150
|
-
requestsPerMinute: 60,
|
|
151
|
-
requestsPerHour: 1000
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// DDoS Protection
|
|
156
|
-
class DDoSProtection {
|
|
157
|
-
private connectionTracker: Map<string, ConnectionInfo> = new Map();
|
|
158
|
-
|
|
159
|
-
async handleRequest(request: Request): Promise<Response | null> {
|
|
160
|
-
const clientIp = request.headers.get('cf-connecting-ip')!;
|
|
161
|
-
|
|
162
|
-
// Check if IP is in blocklist
|
|
163
|
-
if (await this.isBlocked(clientIp)) {
|
|
164
|
-
return new Response('Blocked', { status: 403 });
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Track connection patterns
|
|
168
|
-
const info = this.trackConnection(clientIp);
|
|
169
|
-
|
|
170
|
-
// Detect anomalies
|
|
171
|
-
if (this.isAnomalous(info)) {
|
|
172
|
-
await this.triggerProtection(clientIp);
|
|
173
|
-
return new Response('Rate Limited', { status: 429 });
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return null; // Allow through
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
private isAnomalous(info: ConnectionInfo): boolean {
|
|
180
|
-
return (
|
|
181
|
-
info.requestsPerSecond > 100 ||
|
|
182
|
-
info.uniquePathsPerMinute > 500 ||
|
|
183
|
-
info.payloadSize > 10_000_000
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### 3. Layer 2: Network Security
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
/**
|
|
193
|
-
* Network Security: Isolate and protect internal communication
|
|
194
|
-
*/
|
|
195
|
-
|
|
196
|
-
// VPC and Security Group Configuration (AWS example)
|
|
197
|
-
const networkConfig = {
|
|
198
|
-
vpc: {
|
|
199
|
-
cidr: '10.0.0.0/16',
|
|
200
|
-
subnets: {
|
|
201
|
-
public: ['10.0.1.0/24', '10.0.2.0/24'], // Load balancers
|
|
202
|
-
private: ['10.0.10.0/24', '10.0.11.0/24'], // Application
|
|
203
|
-
data: ['10.0.20.0/24', '10.0.21.0/24'] // Databases
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
|
|
207
|
-
securityGroups: {
|
|
208
|
-
loadBalancer: {
|
|
209
|
-
inbound: [
|
|
210
|
-
{ port: 443, source: '0.0.0.0/0' },
|
|
211
|
-
{ port: 80, source: '0.0.0.0/0' } // Redirect to HTTPS
|
|
212
|
-
],
|
|
213
|
-
outbound: [
|
|
214
|
-
{ port: 8080, destination: 'application-sg' }
|
|
215
|
-
]
|
|
216
|
-
},
|
|
217
|
-
|
|
218
|
-
application: {
|
|
219
|
-
inbound: [
|
|
220
|
-
{ port: 8080, source: 'load-balancer-sg' }
|
|
221
|
-
],
|
|
222
|
-
outbound: [
|
|
223
|
-
{ port: 5432, destination: 'database-sg' },
|
|
224
|
-
{ port: 6379, destination: 'cache-sg' },
|
|
225
|
-
{ port: 443, destination: '0.0.0.0/0' } // External APIs
|
|
226
|
-
]
|
|
227
|
-
},
|
|
228
|
-
|
|
229
|
-
database: {
|
|
230
|
-
inbound: [
|
|
231
|
-
{ port: 5432, source: 'application-sg' }
|
|
232
|
-
],
|
|
233
|
-
outbound: [] // No outbound access
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
// Mutual TLS (mTLS) for Service-to-Service
|
|
239
|
-
class MTLSClient {
|
|
240
|
-
private certificate: Certificate;
|
|
241
|
-
private privateKey: PrivateKey;
|
|
242
|
-
private caCertificate: Certificate;
|
|
243
|
-
|
|
244
|
-
async makeRequest(url: string, options: RequestInit): Promise<Response> {
|
|
245
|
-
const agent = new https.Agent({
|
|
246
|
-
cert: this.certificate,
|
|
247
|
-
key: this.privateKey,
|
|
248
|
-
ca: this.caCertificate,
|
|
249
|
-
rejectUnauthorized: true
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
return fetch(url, {
|
|
253
|
-
...options,
|
|
254
|
-
// @ts-ignore
|
|
255
|
-
agent
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Network Policy (Kubernetes)
|
|
261
|
-
const networkPolicy = {
|
|
262
|
-
apiVersion: 'networking.k8s.io/v1',
|
|
263
|
-
kind: 'NetworkPolicy',
|
|
264
|
-
metadata: {
|
|
265
|
-
name: 'api-server-policy',
|
|
266
|
-
namespace: 'production'
|
|
267
|
-
},
|
|
268
|
-
spec: {
|
|
269
|
-
podSelector: {
|
|
270
|
-
matchLabels: { app: 'api-server' }
|
|
271
|
-
},
|
|
272
|
-
policyTypes: ['Ingress', 'Egress'],
|
|
273
|
-
ingress: [
|
|
274
|
-
{
|
|
275
|
-
from: [
|
|
276
|
-
{ podSelector: { matchLabels: { app: 'ingress-controller' } } }
|
|
277
|
-
],
|
|
278
|
-
ports: [{ port: 8080, protocol: 'TCP' }]
|
|
279
|
-
}
|
|
280
|
-
],
|
|
281
|
-
egress: [
|
|
282
|
-
{
|
|
283
|
-
to: [
|
|
284
|
-
{ podSelector: { matchLabels: { app: 'database' } } }
|
|
285
|
-
],
|
|
286
|
-
ports: [{ port: 5432, protocol: 'TCP' }]
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
to: [
|
|
290
|
-
{ namespaceSelector: { matchLabels: { name: 'kube-system' } } }
|
|
291
|
-
],
|
|
292
|
-
ports: [{ port: 53, protocol: 'UDP' }] // DNS
|
|
293
|
-
}
|
|
294
|
-
]
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### 4. Layer 3: Application Security
|
|
300
|
-
|
|
301
|
-
```typescript
|
|
302
|
-
/**
|
|
303
|
-
* Application Security: Secure code and request handling
|
|
304
|
-
*/
|
|
305
|
-
|
|
306
|
-
import { z } from 'zod';
|
|
307
|
-
import DOMPurify from 'dompurify';
|
|
308
|
-
import csrf from 'csrf';
|
|
309
|
-
|
|
310
|
-
// Input Validation - Never trust user input
|
|
311
|
-
const userInputSchema = z.object({
|
|
312
|
-
email: z.string().email().max(254),
|
|
313
|
-
name: z.string().min(1).max(100).regex(/^[\p{L}\s'-]+$/u),
|
|
314
|
-
age: z.number().int().min(0).max(150).optional(),
|
|
315
|
-
bio: z.string().max(1000).optional()
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
function validateInput<T>(schema: z.ZodSchema<T>, data: unknown): T {
|
|
319
|
-
try {
|
|
320
|
-
return schema.parse(data);
|
|
321
|
-
} catch (error) {
|
|
322
|
-
if (error instanceof z.ZodError) {
|
|
323
|
-
throw new ValidationError(error.errors);
|
|
324
|
-
}
|
|
325
|
-
throw error;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Output Encoding - Prevent XSS
|
|
330
|
-
function sanitizeForHTML(input: string): string {
|
|
331
|
-
return DOMPurify.sanitize(input, {
|
|
332
|
-
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br'],
|
|
333
|
-
ALLOWED_ATTR: ['href', 'title'],
|
|
334
|
-
ALLOW_DATA_ATTR: false
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
function escapeForSQL(input: string): string {
|
|
339
|
-
// Always use parameterized queries instead!
|
|
340
|
-
throw new Error('Use parameterized queries, not escaping');
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// CSRF Protection
|
|
344
|
-
class CSRFProtection {
|
|
345
|
-
private tokens = new csrf();
|
|
346
|
-
|
|
347
|
-
generateToken(sessionId: string): string {
|
|
348
|
-
const secret = this.getSecretForSession(sessionId);
|
|
349
|
-
return this.tokens.create(secret);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
verifyToken(sessionId: string, token: string): boolean {
|
|
353
|
-
const secret = this.getSecretForSession(sessionId);
|
|
354
|
-
return this.tokens.verify(secret, token);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Content Security Policy
|
|
359
|
-
const contentSecurityPolicy = {
|
|
360
|
-
'default-src': ["'self'"],
|
|
361
|
-
'script-src': ["'self'", "'strict-dynamic'"],
|
|
362
|
-
'style-src': ["'self'", "'unsafe-inline'"], // Consider using nonces
|
|
363
|
-
'img-src': ["'self'", 'data:', 'https:'],
|
|
364
|
-
'font-src': ["'self'"],
|
|
365
|
-
'connect-src': ["'self'", 'https://api.example.com'],
|
|
366
|
-
'frame-ancestors': ["'none'"],
|
|
367
|
-
'base-uri': ["'self'"],
|
|
368
|
-
'form-action': ["'self'"]
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
// Security Headers Middleware
|
|
372
|
-
function securityHeaders(req: Request, res: Response, next: NextFunction) {
|
|
373
|
-
// Prevent clickjacking
|
|
374
|
-
res.setHeader('X-Frame-Options', 'DENY');
|
|
375
|
-
|
|
376
|
-
// Prevent MIME sniffing
|
|
377
|
-
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
378
|
-
|
|
379
|
-
// Enable XSS filter (legacy browsers)
|
|
380
|
-
res.setHeader('X-XSS-Protection', '1; mode=block');
|
|
381
|
-
|
|
382
|
-
// Force HTTPS
|
|
383
|
-
res.setHeader(
|
|
384
|
-
'Strict-Transport-Security',
|
|
385
|
-
'max-age=31536000; includeSubDomains; preload'
|
|
386
|
-
);
|
|
387
|
-
|
|
388
|
-
// CSP
|
|
389
|
-
const cspValue = Object.entries(contentSecurityPolicy)
|
|
390
|
-
.map(([key, values]) => `${key} ${values.join(' ')}`)
|
|
391
|
-
.join('; ');
|
|
392
|
-
res.setHeader('Content-Security-Policy', cspValue);
|
|
393
|
-
|
|
394
|
-
next();
|
|
395
|
-
}
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### 5. Layer 4: Data Security
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
/**
|
|
402
|
-
* Data Security: Protect data at rest and in transit
|
|
403
|
-
*/
|
|
404
|
-
|
|
405
|
-
import { createCipheriv, createDecipheriv, randomBytes, scrypt } from 'crypto';
|
|
406
|
-
|
|
407
|
-
// Encryption at Rest
|
|
408
|
-
class FieldLevelEncryption {
|
|
409
|
-
private algorithm = 'aes-256-gcm';
|
|
410
|
-
private keyLength = 32;
|
|
411
|
-
private ivLength = 16;
|
|
412
|
-
private tagLength = 16;
|
|
413
|
-
|
|
414
|
-
async encrypt(
|
|
415
|
-
plaintext: string,
|
|
416
|
-
encryptionKey: Buffer
|
|
417
|
-
): Promise<EncryptedData> {
|
|
418
|
-
const iv = randomBytes(this.ivLength);
|
|
419
|
-
const cipher = createCipheriv(this.algorithm, encryptionKey, iv);
|
|
420
|
-
|
|
421
|
-
let encrypted = cipher.update(plaintext, 'utf8', 'base64');
|
|
422
|
-
encrypted += cipher.final('base64');
|
|
423
|
-
|
|
424
|
-
const tag = cipher.getAuthTag();
|
|
425
|
-
|
|
426
|
-
return {
|
|
427
|
-
ciphertext: encrypted,
|
|
428
|
-
iv: iv.toString('base64'),
|
|
429
|
-
tag: tag.toString('base64'),
|
|
430
|
-
algorithm: this.algorithm
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
async decrypt(
|
|
435
|
-
data: EncryptedData,
|
|
436
|
-
encryptionKey: Buffer
|
|
437
|
-
): Promise<string> {
|
|
438
|
-
const decipher = createDecipheriv(
|
|
439
|
-
data.algorithm,
|
|
440
|
-
encryptionKey,
|
|
441
|
-
Buffer.from(data.iv, 'base64')
|
|
442
|
-
);
|
|
19
|
+
| Feature | Description | Guide |
|
|
20
|
+
|---------|-------------|-------|
|
|
21
|
+
| Layered Protection | 5+ independent security barriers | Each layer catches what others miss |
|
|
22
|
+
| Perimeter Security | First line of defense | WAF rules, rate limits, DDoS protection |
|
|
23
|
+
| Network Isolation | Segment and protect internal comms | VPC subnets, security groups, mTLS |
|
|
24
|
+
| Application Security | Secure code and request handling | Validate input, encode output, CSP headers |
|
|
25
|
+
| Data Protection | Protect data at rest and in transit | AES-256-GCM, field-level encryption |
|
|
26
|
+
| Identity Security | Authentication and authorization | MFA, RBAC, secure sessions |
|
|
443
27
|
|
|
444
|
-
|
|
28
|
+
## Common Patterns
|
|
445
29
|
|
|
446
|
-
let decrypted = decipher.update(data.ciphertext, 'base64', 'utf8');
|
|
447
|
-
decrypted += decipher.final('utf8');
|
|
448
|
-
|
|
449
|
-
return decrypted;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// Data Classification and Handling
|
|
454
|
-
type DataClassification = 'public' | 'internal' | 'confidential' | 'restricted';
|
|
455
|
-
|
|
456
|
-
interface DataHandlingPolicy {
|
|
457
|
-
classification: DataClassification;
|
|
458
|
-
encryption: {
|
|
459
|
-
atRest: boolean;
|
|
460
|
-
inTransit: boolean;
|
|
461
|
-
};
|
|
462
|
-
accessControl: {
|
|
463
|
-
roles: string[];
|
|
464
|
-
mfa: boolean;
|
|
465
|
-
};
|
|
466
|
-
retention: {
|
|
467
|
-
maxDays: number;
|
|
468
|
-
archiveAfterDays?: number;
|
|
469
|
-
};
|
|
470
|
-
logging: {
|
|
471
|
-
accessLogging: boolean;
|
|
472
|
-
auditLogging: boolean;
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const dataHandlingPolicies: Record<DataClassification, DataHandlingPolicy> = {
|
|
477
|
-
public: {
|
|
478
|
-
classification: 'public',
|
|
479
|
-
encryption: { atRest: false, inTransit: true },
|
|
480
|
-
accessControl: { roles: ['*'], mfa: false },
|
|
481
|
-
retention: { maxDays: 365 * 10 },
|
|
482
|
-
logging: { accessLogging: false, auditLogging: false }
|
|
483
|
-
},
|
|
484
|
-
internal: {
|
|
485
|
-
classification: 'internal',
|
|
486
|
-
encryption: { atRest: false, inTransit: true },
|
|
487
|
-
accessControl: { roles: ['employee'], mfa: false },
|
|
488
|
-
retention: { maxDays: 365 * 5 },
|
|
489
|
-
logging: { accessLogging: true, auditLogging: false }
|
|
490
|
-
},
|
|
491
|
-
confidential: {
|
|
492
|
-
classification: 'confidential',
|
|
493
|
-
encryption: { atRest: true, inTransit: true },
|
|
494
|
-
accessControl: { roles: ['authorized'], mfa: true },
|
|
495
|
-
retention: { maxDays: 365 * 3, archiveAfterDays: 365 },
|
|
496
|
-
logging: { accessLogging: true, auditLogging: true }
|
|
497
|
-
},
|
|
498
|
-
restricted: {
|
|
499
|
-
classification: 'restricted',
|
|
500
|
-
encryption: { atRest: true, inTransit: true },
|
|
501
|
-
accessControl: { roles: ['privileged'], mfa: true },
|
|
502
|
-
retention: { maxDays: 365, archiveAfterDays: 90 },
|
|
503
|
-
logging: { accessLogging: true, auditLogging: true }
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
// Database Access Control
|
|
508
|
-
class SecureDataAccess {
|
|
509
|
-
async query<T>(
|
|
510
|
-
sql: string,
|
|
511
|
-
params: unknown[],
|
|
512
|
-
context: SecurityContext
|
|
513
|
-
): Promise<T[]> {
|
|
514
|
-
// 1. Always use parameterized queries
|
|
515
|
-
// 2. Apply row-level security
|
|
516
|
-
const securedSql = this.applyRowLevelSecurity(sql, context);
|
|
517
|
-
|
|
518
|
-
// 3. Audit the access
|
|
519
|
-
await this.auditLog({
|
|
520
|
-
action: 'data_access',
|
|
521
|
-
query: sql,
|
|
522
|
-
user: context.userId,
|
|
523
|
-
timestamp: new Date(),
|
|
524
|
-
classification: this.getDataClassification(sql)
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
// 4. Execute with minimal privileges
|
|
528
|
-
return this.executeWithRole(securedSql, params, context.dbRole);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
30
|
```
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
return this.verifyOTP(userId, method, code);
|
|
564
|
-
default:
|
|
565
|
-
throw new Error(`Unsupported MFA method: ${method}`);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
private async verifyTOTP(userId: string, code: string): Promise<boolean> {
|
|
570
|
-
const secret = await this.getTOTPSecret(userId);
|
|
571
|
-
const expected = this.generateTOTP(secret);
|
|
572
|
-
|
|
573
|
-
// Check current and adjacent time windows
|
|
574
|
-
const windows = [-1, 0, 1];
|
|
575
|
-
return windows.some(offset =>
|
|
576
|
-
this.generateTOTP(secret, offset) === code
|
|
577
|
-
);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
// Principle of Least Privilege
|
|
582
|
-
interface Permission {
|
|
583
|
-
resource: string;
|
|
584
|
-
actions: string[];
|
|
585
|
-
conditions?: PermissionCondition[];
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
interface Role {
|
|
589
|
-
name: string;
|
|
590
|
-
permissions: Permission[];
|
|
591
|
-
inherits?: string[];
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
const roleDefinitions: Role[] = [
|
|
595
|
-
{
|
|
596
|
-
name: 'viewer',
|
|
597
|
-
permissions: [
|
|
598
|
-
{ resource: 'documents', actions: ['read'] },
|
|
599
|
-
{ resource: 'comments', actions: ['read', 'create'] }
|
|
600
|
-
]
|
|
601
|
-
},
|
|
602
|
-
{
|
|
603
|
-
name: 'editor',
|
|
604
|
-
inherits: ['viewer'],
|
|
605
|
-
permissions: [
|
|
606
|
-
{ resource: 'documents', actions: ['read', 'write', 'delete'] },
|
|
607
|
-
{
|
|
608
|
-
resource: 'documents',
|
|
609
|
-
actions: ['publish'],
|
|
610
|
-
conditions: [{ type: 'ownership', field: 'authorId' }]
|
|
611
|
-
}
|
|
612
|
-
]
|
|
613
|
-
},
|
|
614
|
-
{
|
|
615
|
-
name: 'admin',
|
|
616
|
-
inherits: ['editor'],
|
|
617
|
-
permissions: [
|
|
618
|
-
{ resource: 'users', actions: ['read', 'write', 'delete'] },
|
|
619
|
-
{ resource: 'settings', actions: ['read', 'write'] }
|
|
620
|
-
]
|
|
621
|
-
}
|
|
622
|
-
];
|
|
623
|
-
|
|
624
|
-
// Session Security
|
|
625
|
-
class SecureSessionManager {
|
|
626
|
-
private readonly SESSION_DURATION = 3600; // 1 hour
|
|
627
|
-
private readonly REFRESH_THRESHOLD = 300; // 5 minutes
|
|
628
|
-
|
|
629
|
-
async createSession(userId: string, metadata: SessionMetadata): Promise<Session> {
|
|
630
|
-
const sessionId = this.generateSecureId();
|
|
631
|
-
const session: Session = {
|
|
632
|
-
id: sessionId,
|
|
633
|
-
userId,
|
|
634
|
-
createdAt: new Date(),
|
|
635
|
-
expiresAt: new Date(Date.now() + this.SESSION_DURATION * 1000),
|
|
636
|
-
metadata: {
|
|
637
|
-
...metadata,
|
|
638
|
-
userAgent: metadata.userAgent,
|
|
639
|
-
ipAddress: metadata.ipAddress,
|
|
640
|
-
mfaVerified: false
|
|
641
|
-
}
|
|
642
|
-
};
|
|
643
|
-
|
|
644
|
-
await this.store.set(sessionId, session);
|
|
645
|
-
return session;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
async validateSession(sessionId: string, request: Request): Promise<Session | null> {
|
|
649
|
-
const session = await this.store.get(sessionId);
|
|
650
|
-
|
|
651
|
-
if (!session) return null;
|
|
652
|
-
|
|
653
|
-
// Check expiration
|
|
654
|
-
if (new Date() > session.expiresAt) {
|
|
655
|
-
await this.invalidateSession(sessionId);
|
|
656
|
-
return null;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
// Validate session binding (prevent session hijacking)
|
|
660
|
-
if (!this.validateSessionBinding(session, request)) {
|
|
661
|
-
await this.invalidateSession(sessionId);
|
|
662
|
-
await this.alertSecurityTeam('session_hijacking_attempt', session);
|
|
663
|
-
return null;
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// Refresh if close to expiry
|
|
667
|
-
if (this.shouldRefresh(session)) {
|
|
668
|
-
await this.refreshSession(session);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
return session;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
private validateSessionBinding(session: Session, request: Request): boolean {
|
|
675
|
-
// Check IP address consistency (with some tolerance for mobile)
|
|
676
|
-
const currentIp = request.headers.get('x-forwarded-for');
|
|
677
|
-
if (session.metadata.ipAddress !== currentIp) {
|
|
678
|
-
// Log but allow if user agent matches (mobile networks change IPs)
|
|
679
|
-
if (session.metadata.userAgent !== request.headers.get('user-agent')) {
|
|
680
|
-
return false;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
return true;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
31
|
+
# Security Layers Architecture
|
|
32
|
+
+--------------------------------------------------+
|
|
33
|
+
| LAYER 1: PERIMETER |
|
|
34
|
+
| WAF | DDoS | Rate Limiting | IP Filtering |
|
|
35
|
+
+--------------------------------------------------+
|
|
36
|
+
|
|
|
37
|
+
v
|
|
38
|
+
+--------------------------------------------------+
|
|
39
|
+
| LAYER 2: NETWORK |
|
|
40
|
+
| VPC | Security Groups | TLS Everywhere |
|
|
41
|
+
+--------------------------------------------------+
|
|
42
|
+
|
|
|
43
|
+
v
|
|
44
|
+
+--------------------------------------------------+
|
|
45
|
+
| LAYER 3: APPLICATION |
|
|
46
|
+
| Input Validation | Output Encoding | CSRF | CSP |
|
|
47
|
+
+--------------------------------------------------+
|
|
48
|
+
|
|
|
49
|
+
v
|
|
50
|
+
+--------------------------------------------------+
|
|
51
|
+
| LAYER 4: DATA |
|
|
52
|
+
| Encryption at Rest | Encryption in Transit |
|
|
53
|
+
+--------------------------------------------------+
|
|
54
|
+
|
|
|
55
|
+
v
|
|
56
|
+
+--------------------------------------------------+
|
|
57
|
+
| LAYER 5: IDENTITY |
|
|
58
|
+
| MFA | Least Privilege | Session Management |
|
|
59
|
+
+--------------------------------------------------+
|
|
60
|
+
|
|
61
|
+
CROSS-CUTTING: Logging | Alerting | Anomaly Detection
|
|
686
62
|
```
|
|
687
63
|
|
|
688
|
-
### 7. Cross-Cutting: Monitoring and Detection
|
|
689
|
-
|
|
690
|
-
```typescript
|
|
691
|
-
/**
|
|
692
|
-
* Security Monitoring: Detect and respond to threats
|
|
693
|
-
*/
|
|
694
|
-
|
|
695
|
-
interface SecurityEvent {
|
|
696
|
-
timestamp: Date;
|
|
697
|
-
eventType: SecurityEventType;
|
|
698
|
-
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
699
|
-
source: string;
|
|
700
|
-
target: string;
|
|
701
|
-
details: Record<string, unknown>;
|
|
702
|
-
userId?: string;
|
|
703
|
-
ipAddress?: string;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
type SecurityEventType =
|
|
707
|
-
| 'authentication_failure'
|
|
708
|
-
| 'authorization_failure'
|
|
709
|
-
| 'rate_limit_exceeded'
|
|
710
|
-
| 'suspicious_pattern'
|
|
711
|
-
| 'data_access_anomaly'
|
|
712
|
-
| 'configuration_change'
|
|
713
|
-
| 'privilege_escalation'
|
|
714
|
-
| 'sql_injection_attempt'
|
|
715
|
-
| 'xss_attempt';
|
|
716
|
-
|
|
717
|
-
class SecurityMonitoring {
|
|
718
|
-
private readonly alertThresholds = {
|
|
719
|
-
authentication_failure: { count: 5, windowMinutes: 5 },
|
|
720
|
-
rate_limit_exceeded: { count: 10, windowMinutes: 1 },
|
|
721
|
-
sql_injection_attempt: { count: 1, windowMinutes: 1 }
|
|
722
|
-
};
|
|
723
|
-
|
|
724
|
-
async logSecurityEvent(event: SecurityEvent): Promise<void> {
|
|
725
|
-
// 1. Store the event
|
|
726
|
-
await this.eventStore.insert(event);
|
|
727
|
-
|
|
728
|
-
// 2. Check for alerting conditions
|
|
729
|
-
await this.checkAlertConditions(event);
|
|
730
|
-
|
|
731
|
-
// 3. Update metrics
|
|
732
|
-
this.metrics.increment(`security_events_${event.eventType}`, {
|
|
733
|
-
severity: event.severity
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
private async checkAlertConditions(event: SecurityEvent): Promise<void> {
|
|
738
|
-
const threshold = this.alertThresholds[event.eventType];
|
|
739
|
-
if (!threshold) return;
|
|
740
|
-
|
|
741
|
-
const recentCount = await this.countRecentEvents(
|
|
742
|
-
event.eventType,
|
|
743
|
-
event.source,
|
|
744
|
-
threshold.windowMinutes
|
|
745
|
-
);
|
|
746
|
-
|
|
747
|
-
if (recentCount >= threshold.count) {
|
|
748
|
-
await this.triggerAlert({
|
|
749
|
-
type: 'threshold_exceeded',
|
|
750
|
-
event,
|
|
751
|
-
count: recentCount,
|
|
752
|
-
threshold: threshold.count
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
async detectAnomalies(): Promise<Anomaly[]> {
|
|
758
|
-
const anomalies: Anomaly[] = [];
|
|
759
|
-
|
|
760
|
-
// Check for unusual access patterns
|
|
761
|
-
const accessPatterns = await this.analyzeAccessPatterns();
|
|
762
|
-
anomalies.push(...accessPatterns.filter(p => p.isAnomalous));
|
|
763
|
-
|
|
764
|
-
// Check for privilege escalation attempts
|
|
765
|
-
const privilegeEvents = await this.analyzePrivilegeEvents();
|
|
766
|
-
anomalies.push(...privilegeEvents.filter(e => e.isAnomalous));
|
|
767
|
-
|
|
768
|
-
// Check for data exfiltration patterns
|
|
769
|
-
const dataAccess = await this.analyzeDataAccessPatterns();
|
|
770
|
-
anomalies.push(...dataAccess.filter(d => d.isAnomalous));
|
|
771
|
-
|
|
772
|
-
return anomalies;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
64
|
```
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
app.use(rateLimit({
|
|
789
|
-
windowMs: 60 * 1000,
|
|
790
|
-
max: 100,
|
|
791
|
-
standardHeaders: true,
|
|
792
|
-
legacyHeaders: false
|
|
793
|
-
}));
|
|
794
|
-
|
|
795
|
-
// Layer 2: Security headers (Network/Application)
|
|
796
|
-
app.use(helmet());
|
|
797
|
-
app.use(cors({ origin: allowedOrigins, credentials: true }));
|
|
798
|
-
|
|
799
|
-
// Layer 3: Request validation (Application)
|
|
800
|
-
app.use(express.json({ limit: '100kb' }));
|
|
801
|
-
|
|
802
|
-
// Layer 4: Authentication (Identity)
|
|
803
|
-
app.use(authMiddleware);
|
|
804
|
-
|
|
805
|
-
// Layer 5: Authorization per route (Identity)
|
|
806
|
-
app.get('/api/users/:id',
|
|
807
|
-
authorize(['admin', 'self']),
|
|
808
|
-
async (req, res) => {
|
|
809
|
-
// Layer 6: Data access with security context
|
|
810
|
-
const user = await secureDataAccess.getUser(req.params.id, req.securityContext);
|
|
811
|
-
res.json(user);
|
|
812
|
-
}
|
|
813
|
-
);
|
|
814
|
-
|
|
815
|
-
// Cross-cutting: Error handling with security logging
|
|
816
|
-
app.use(securityErrorHandler);
|
|
65
|
+
# Network Security Groups (Example)
|
|
66
|
+
loadBalancer:
|
|
67
|
+
inbound: [443 from 0.0.0.0/0]
|
|
68
|
+
outbound: [8080 to application-sg]
|
|
69
|
+
|
|
70
|
+
application:
|
|
71
|
+
inbound: [8080 from load-balancer-sg]
|
|
72
|
+
outbound: [5432 to database-sg, 443 to external]
|
|
73
|
+
|
|
74
|
+
database:
|
|
75
|
+
inbound: [5432 from application-sg]
|
|
76
|
+
outbound: [] # No outbound
|
|
817
77
|
```
|
|
818
78
|
|
|
819
79
|
## Best Practices
|
|
820
80
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
-
|
|
836
|
-
-
|
|
837
|
-
-
|
|
838
|
-
- Don't store secrets in code
|
|
839
|
-
- Don't skip security in development
|
|
840
|
-
- Don't ignore security alerts
|
|
841
|
-
- Don't assume internal traffic is safe
|
|
842
|
-
- Don't disable security for "convenience"
|
|
843
|
-
|
|
844
|
-
## References
|
|
845
|
-
|
|
846
|
-
- [OWASP Security Cheat Sheets](https://cheatsheetseries.owasp.org/)
|
|
847
|
-
- [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
|
|
848
|
-
- [AWS Well-Architected Security Pillar](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/)
|
|
849
|
-
- [Zero Trust Architecture](https://www.nist.gov/publications/zero-trust-architecture)
|
|
81
|
+
| Do | Avoid |
|
|
82
|
+
|----|-------|
|
|
83
|
+
| Implement all layers - each provides unique protection | Relying on a single security layer |
|
|
84
|
+
| Fail securely - deny access when in doubt | Trusting user input at any layer |
|
|
85
|
+
| Log security events for detection/forensics | Exposing detailed error messages |
|
|
86
|
+
| Rotate credentials regularly | Storing secrets in code |
|
|
87
|
+
| Validate all inputs at every layer | Skipping security in development |
|
|
88
|
+
| Encrypt sensitive data at rest and in transit | Assuming internal traffic is safe |
|
|
89
|
+
| Use least privilege for all access | Disabling security for "convenience" |
|
|
90
|
+
| Test security controls regularly | Ignoring security alerts |
|
|
91
|
+
|
|
92
|
+
## Related Skills
|
|
93
|
+
|
|
94
|
+
- `applying-owasp-security` - OWASP security guidelines
|
|
95
|
+
- `implementing-oauth` - OAuth authentication flows
|
|
96
|
+
- `implementing-better-auth` - Modern auth patterns
|
|
97
|
+
- `verifying-before-completion` - Security verification checklists
|