@minko-ai/minko 0.1.0 → 0.1.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.
Files changed (189) hide show
  1. package/README.md +577 -2
  2. package/assets/mascot-preview.png +0 -0
  3. package/assets/mascot-preview.txt +46 -0
  4. package/assets/mascot-source.png +0 -0
  5. package/assets/skills/README.md +21 -0
  6. package/assets/skills/brainstorming/LICENSE +21 -0
  7. package/assets/skills/brainstorming/SKILL.md +316 -0
  8. package/assets/skills/buddhist-method/LICENSE +21 -0
  9. package/assets/skills/buddhist-method/SKILL.md +137 -0
  10. package/assets/skills/buddhist-method/references/ariyasacca-debug.md +57 -0
  11. package/assets/skills/buddhist-method/references/extended-principles.md +100 -0
  12. package/assets/skills/code-humanizer/LICENSE +21 -0
  13. package/assets/skills/code-humanizer/SKILL.md +174 -0
  14. package/assets/skills/code-review/LICENSE +21 -0
  15. package/assets/skills/code-review/SKILL.md +232 -0
  16. package/assets/skills/code-review/reference/angular.md +768 -0
  17. package/assets/skills/code-review/reference/architecture-review-guide.md +472 -0
  18. package/assets/skills/code-review/reference/c.md +890 -0
  19. package/assets/skills/code-review/reference/code-quality-universal.md +488 -0
  20. package/assets/skills/code-review/reference/code-review-best-practices.md +136 -0
  21. package/assets/skills/code-review/reference/common-bugs-checklist.md +302 -0
  22. package/assets/skills/code-review/reference/cpp.md +893 -0
  23. package/assets/skills/code-review/reference/cross-cutting/async-concurrency-patterns.md +515 -0
  24. package/assets/skills/code-review/reference/cross-cutting/error-handling-principles.md +492 -0
  25. package/assets/skills/code-review/reference/cross-cutting/n-plus-one-queries.md +309 -0
  26. package/assets/skills/code-review/reference/cross-cutting/sql-injection-prevention.md +308 -0
  27. package/assets/skills/code-review/reference/cross-cutting/xss-prevention.md +264 -0
  28. package/assets/skills/code-review/reference/csharp.md +525 -0
  29. package/assets/skills/code-review/reference/css-less-sass.md +661 -0
  30. package/assets/skills/code-review/reference/dart.md +670 -0
  31. package/assets/skills/code-review/reference/django.md +985 -0
  32. package/assets/skills/code-review/reference/fastapi.md +580 -0
  33. package/assets/skills/code-review/reference/go.md +993 -0
  34. package/assets/skills/code-review/reference/java.md +409 -0
  35. package/assets/skills/code-review/reference/java8.md +586 -0
  36. package/assets/skills/code-review/reference/kotlin.md +1018 -0
  37. package/assets/skills/code-review/reference/nestjs.md +593 -0
  38. package/assets/skills/code-review/reference/performance-review-guide.md +816 -0
  39. package/assets/skills/code-review/reference/php.md +684 -0
  40. package/assets/skills/code-review/reference/python.md +1073 -0
  41. package/assets/skills/code-review/reference/qt.md +757 -0
  42. package/assets/skills/code-review/reference/react.md +871 -0
  43. package/assets/skills/code-review/reference/ruby.md +964 -0
  44. package/assets/skills/code-review/reference/rust.md +846 -0
  45. package/assets/skills/code-review/reference/security-review-guide.md +494 -0
  46. package/assets/skills/code-review/reference/svelte.md +1064 -0
  47. package/assets/skills/code-review/reference/swift.md +936 -0
  48. package/assets/skills/code-review/reference/typescript.md +1016 -0
  49. package/assets/skills/code-review/reference/vue.md +924 -0
  50. package/assets/skills/code-review/reference/zig.md +440 -0
  51. package/assets/skills/cyclomatic-complexity/LICENSE +201 -0
  52. package/assets/skills/cyclomatic-complexity/SKILL.md +69 -0
  53. package/assets/skills/five-whys/LICENSE +21 -0
  54. package/assets/skills/five-whys/SKILL.md +247 -0
  55. package/assets/skills/five-whys/examples/performance-regression.md +161 -0
  56. package/assets/skills/five-whys/examples/production-incident.md +134 -0
  57. package/assets/skills/five-whys/references/software-patterns.md +284 -0
  58. package/assets/skills/five-whys/references/toyota-origins.md +257 -0
  59. package/assets/skills/systematic-debugging/LICENSE +21 -0
  60. package/assets/skills/systematic-debugging/SKILL.md +283 -0
  61. package/assets/skills/test-driven-development/LICENSE +21 -0
  62. package/assets/skills/test-driven-development/SKILL.md +330 -0
  63. package/assets/skills/verification-before-completion/LICENSE +21 -0
  64. package/assets/skills/verification-before-completion/SKILL.md +120 -0
  65. package/assets/skills/vibe-sec/LICENSE +201 -0
  66. package/assets/skills/vibe-sec/SKILL.md +758 -0
  67. package/assets/skills/writing-plans/LICENSE +21 -0
  68. package/assets/skills/writing-plans/SKILL.md +204 -0
  69. package/bin/minko.js +2 -2
  70. package/dist/agent/approvalTokens.js +224 -0
  71. package/dist/agent/branchLock.js +315 -0
  72. package/dist/agent/compact.js +182 -0
  73. package/dist/agent/context.js +183 -0
  74. package/dist/agent/cron.js +326 -0
  75. package/dist/agent/hooks.js +211 -0
  76. package/dist/agent/lanes.js +511 -0
  77. package/dist/agent/loop.js +337 -0
  78. package/dist/agent/memory.js +159 -0
  79. package/dist/agent/permissions.js +71 -0
  80. package/dist/agent/plan.js +118 -0
  81. package/dist/agent/prompt.js +120 -0
  82. package/dist/agent/subagent.js +67 -0
  83. package/dist/agent/tasks.js +449 -0
  84. package/dist/agent/transcript.js +62 -0
  85. package/dist/agent/workerStore.js +172 -0
  86. package/dist/agent/workerTypes.js +1 -0
  87. package/dist/agent/workers.js +503 -0
  88. package/dist/cli/app.js +261 -0
  89. package/dist/cli/argv.js +206 -0
  90. package/dist/cli/commandsCommand.js +12 -0
  91. package/dist/cli/configCommand.js +170 -0
  92. package/dist/cli/doctorCommand.js +112 -0
  93. package/dist/cli/exportCommand.js +85 -0
  94. package/dist/cli/forkCommand.js +24 -0
  95. package/dist/cli/linkCommand.js +272 -0
  96. package/dist/cli/loginCommand.js +69 -0
  97. package/dist/cli/mcpLoginCommand.js +68 -0
  98. package/dist/cli/pluginCommand.js +113 -0
  99. package/dist/cli/powerCommand.js +174 -0
  100. package/dist/cli/promptFooter.js +74 -0
  101. package/dist/cli/relayCommand.js +38 -0
  102. package/dist/cli/sandboxCommand.js +31 -0
  103. package/dist/cli/serveCommand.js +104 -0
  104. package/dist/cli/statusCommand.js +120 -0
  105. package/dist/cli/tui.js +1104 -0
  106. package/dist/commands/registry.js +99 -0
  107. package/dist/config/paths.js +81 -0
  108. package/dist/config/store.js +605 -0
  109. package/dist/index.js +199 -0
  110. package/dist/link/protocol.js +159 -0
  111. package/dist/link/relay.js +184 -0
  112. package/dist/link/server.js +566 -0
  113. package/dist/link/tunnel.js +90 -0
  114. package/dist/lsp/client.js +340 -0
  115. package/dist/lsp/tool.js +177 -0
  116. package/dist/mcp/client.js +469 -0
  117. package/dist/mcp/httpClient.js +191 -0
  118. package/dist/mcp/server.js +206 -0
  119. package/dist/mcp/tools.js +173 -0
  120. package/dist/oauth/device.js +111 -0
  121. package/dist/oauth/store.js +56 -0
  122. package/dist/plugins/loader.js +291 -0
  123. package/dist/plugins/market.js +98 -0
  124. package/dist/providers/anthropic.js +279 -0
  125. package/dist/providers/factory.js +109 -0
  126. package/dist/providers/openai.js +182 -0
  127. package/dist/providers/retry.js +95 -0
  128. package/dist/providers/sse.js +67 -0
  129. package/dist/providers/types.js +10 -0
  130. package/dist/rag/embeddings.js +171 -0
  131. package/dist/rag/index.js +373 -0
  132. package/dist/rag/server.js +167 -0
  133. package/dist/rag/tool.js +148 -0
  134. package/dist/sandbox/index.js +55 -0
  135. package/dist/sdk/server.js +150 -0
  136. package/dist/sdk/session.js +104 -0
  137. package/dist/session/liveness.js +148 -0
  138. package/dist/session/recorder.js +49 -0
  139. package/dist/session/store.js +171 -0
  140. package/dist/skills/index.js +428 -0
  141. package/dist/theme.js +30 -0
  142. package/dist/tools/fs.js +195 -0
  143. package/dist/tools/notebook.js +109 -0
  144. package/dist/tools/registry.js +32 -0
  145. package/dist/tools/search.js +130 -0
  146. package/dist/tools/shell.js +200 -0
  147. package/dist/tools/structured.js +83 -0
  148. package/dist/tools/types.js +1 -0
  149. package/dist/ui/ansi.js +135 -0
  150. package/dist/ui/banner.js +103 -0
  151. package/dist/ui/input.js +49 -0
  152. package/dist/ui/inputModel.js +113 -0
  153. package/dist/ui/keyboard.js +142 -0
  154. package/dist/ui/mascot.js +34 -0
  155. package/dist/ui/mascotData.js +96 -0
  156. package/dist/ui/md.js +183 -0
  157. package/dist/ui/screen.js +49 -0
  158. package/dist/ui/spinner.js +52 -0
  159. package/dist/ui/transcript.js +287 -0
  160. package/dist/util/clipboard.js +53 -0
  161. package/dist/util/errors.js +50 -0
  162. package/dist/util/version.js +12 -0
  163. package/dist/web/fetch.js +168 -0
  164. package/dist/web/search.js +97 -0
  165. package/package.json +45 -36
  166. package/src/agent/loop.ts +0 -159
  167. package/src/agent/prompt.ts +0 -45
  168. package/src/cli/app.ts +0 -396
  169. package/src/cli/argv.ts +0 -139
  170. package/src/cli/configCommand.ts +0 -175
  171. package/src/config/paths.ts +0 -20
  172. package/src/config/store.ts +0 -149
  173. package/src/index.ts +0 -120
  174. package/src/providers/anthropic.ts +0 -215
  175. package/src/providers/openai.ts +0 -158
  176. package/src/providers/sse.ts +0 -57
  177. package/src/providers/types.ts +0 -59
  178. package/src/session/store.ts +0 -125
  179. package/src/theme.ts +0 -41
  180. package/src/tools/fs.ts +0 -143
  181. package/src/tools/registry.ts +0 -19
  182. package/src/tools/shell.ts +0 -120
  183. package/src/tools/types.ts +0 -26
  184. package/src/ui/ansi.ts +0 -110
  185. package/src/ui/banner.ts +0 -39
  186. package/src/ui/input.ts +0 -54
  187. package/src/ui/md.ts +0 -160
  188. package/src/ui/spinner.ts +0 -58
  189. package/src/util/errors.ts +0 -48
@@ -0,0 +1,758 @@
1
+ ---
2
+ name: vibe-sec
3
+ description: This skill helps Claude write secure web applications. Use this when working on any web application or when a user requests a scan or audit to ensure security best practices are followed.
4
+ ---
5
+
6
+ # Secure Coding Guide for Web Applications
7
+
8
+ ## Overview
9
+
10
+ This guide provides comprehensive secure coding practices for web applications. As an AI assistant, your role is to approach code from a **bug hunter's perspective** and make applications **as secure as possible** without breaking functionality.
11
+
12
+ **Key Principles:**
13
+ - Defense in depth: Never rely on a single security control
14
+ - Fail securely: When something fails, fail closed (deny access)
15
+ - Least privilege: Grant minimum permissions necessary
16
+ - Input validation: Never trust user input, validate everything server-side
17
+ - Output encoding: Encode data appropriately for the context it's rendered in
18
+
19
+ ---
20
+
21
+ ## Access Control Issues
22
+
23
+ Access control vulnerabilities occur when users can access resources or perform actions beyond their intended permissions.
24
+
25
+ ### Core Requirements
26
+
27
+ For **every data point and action** that requires authentication:
28
+
29
+ 1. **User-Level Authorization**
30
+ - Each user must only access/modify their own data
31
+ - No user should access data from other users or organizations
32
+ - Always verify ownership at the data layer, not just the route level
33
+
34
+ 2. **Use UUIDs Instead of Sequential IDs**
35
+ - Use UUIDv4 or similar non-guessable identifiers
36
+ - Exception: Only use sequential IDs if explicitly requested by user
37
+
38
+ 3. **Account Lifecycle Handling**
39
+ - When a user is removed from an organization: immediately revoke all access tokens and sessions
40
+ - When an account is deleted/deactivated: invalidate all active sessions and API keys
41
+ - Implement token revocation lists or short-lived tokens with refresh mechanisms
42
+
43
+ ### Authorization Checks Checklist
44
+
45
+ - [ ] Verify user owns the resource on every request (don't trust client-side data)
46
+ - [ ] Check organization membership for multi-tenant apps
47
+ - [ ] Validate role permissions for role-based actions
48
+ - [ ] Re-validate permissions after any privilege change
49
+ - [ ] Check parent resource ownership (e.g., if accessing a comment, verify user owns the parent post)
50
+
51
+ ### Common Pitfalls to Avoid
52
+
53
+ - **IDOR (Insecure Direct Object Reference)**: Always verify the requesting user has permission to access the requested resource ID
54
+ - **Privilege Escalation**: Validate role changes server-side; never trust role info from client
55
+ - **Horizontal Access**: User A accessing User B's resources with the same privilege level
56
+ - **Vertical Access**: Regular user accessing admin functionality
57
+ - **Mass Assignment**: Filter which fields users can update; don't blindly accept all request body fields
58
+
59
+ ### Implementation Pattern
60
+
61
+ ```
62
+ # Pseudocode for secure resource access
63
+ function getResource(resourceId, currentUser):
64
+ resource = database.find(resourceId)
65
+
66
+ if resource is null:
67
+ return 404 # Don't reveal if resource exists
68
+
69
+ if resource.ownerId != currentUser.id:
70
+ if not currentUser.hasOrgAccess(resource.orgId):
71
+ return 404 # Return 404, not 403, to prevent enumeration
72
+
73
+ return resource
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Client-Side Bugs
79
+
80
+ ### Cross-Site Scripting (XSS)
81
+
82
+ Every input controllable by the user—whether directly or indirectly—must be sanitized against XSS.
83
+
84
+ #### Input Sources to Protect
85
+
86
+ **Direct Inputs:**
87
+ - Form fields (email, name, bio, comments, etc.)
88
+ - Search queries
89
+ - File names during upload
90
+ - Rich text editors / WYSIWYG content
91
+
92
+ **Indirect Inputs:**
93
+ - URL parameters and query strings
94
+ - URL fragments (hash values)
95
+ - HTTP headers used in the application (Referer, User-Agent if displayed)
96
+ - Data from third-party APIs displayed to users
97
+ - WebSocket messages
98
+ - postMessage data from iframes
99
+ - LocalStorage/SessionStorage values if rendered
100
+
101
+ **Often Overlooked:**
102
+ - Error messages that reflect user input
103
+ - PDF/document generators that accept HTML
104
+ - Email templates with user data
105
+ - Log viewers in admin panels
106
+ - JSON responses rendered as HTML
107
+ - SVG file uploads (can contain JavaScript)
108
+ - Markdown rendering (if allowing HTML)
109
+
110
+ #### Protection Strategies
111
+
112
+ 1. **Output Encoding** (Context-Specific)
113
+ - HTML context: HTML entity encode (`<` → `&lt;`)
114
+ - JavaScript context: JavaScript escape
115
+ - URL context: URL encode
116
+ - CSS context: CSS escape
117
+ - Use framework's built-in escaping (React's JSX, Vue's {{ }}, etc.)
118
+
119
+ 2. **Content Security Policy (CSP)**
120
+ ```
121
+ Content-Security-Policy:
122
+ default-src 'self';
123
+ script-src 'self';
124
+ style-src 'self' 'unsafe-inline';
125
+ img-src 'self' data: https:;
126
+ font-src 'self';
127
+ connect-src 'self' https://api.yourdomain.com;
128
+ frame-ancestors 'none';
129
+ base-uri 'self';
130
+ form-action 'self';
131
+ ```
132
+ - Avoid `'unsafe-inline'` and `'unsafe-eval'` for scripts
133
+ - Use nonces or hashes for inline scripts when necessary
134
+ - Report violations: `report-uri /csp-report`
135
+
136
+ 3. **Input Sanitization**
137
+ - Use established libraries (DOMPurify for HTML)
138
+ - Whitelist allowed tags/attributes for rich text
139
+ - Strip or encode dangerous patterns
140
+
141
+ 4. **Additional Headers**
142
+ - `X-Content-Type-Options: nosniff`
143
+ - `X-Frame-Options: DENY` (or use CSP frame-ancestors)
144
+
145
+ ---
146
+
147
+ ### Cross-Site Request Forgery (CSRF)
148
+
149
+ Every state-changing endpoint must be protected against CSRF attacks.
150
+
151
+ #### Endpoints Requiring CSRF Protection
152
+
153
+ **Authenticated Actions:**
154
+ - All POST, PUT, PATCH, DELETE requests
155
+ - Any GET request that changes state (fix these to use proper HTTP methods)
156
+ - File uploads
157
+ - Settings changes
158
+ - Payment/transaction endpoints
159
+
160
+ **Pre-Authentication Actions:**
161
+ - Login endpoints (prevent login CSRF)
162
+ - Signup endpoints
163
+ - Password reset request endpoints
164
+ - Password change endpoints
165
+ - Email/phone verification endpoints
166
+ - OAuth callback endpoints
167
+
168
+ #### Protection Mechanisms
169
+
170
+ 1. **CSRF Tokens**
171
+ - Generate cryptographically random tokens
172
+ - Tie token to user session
173
+ - Validate on every state-changing request
174
+ - Regenerate after login (prevent session fixation combo)
175
+
176
+ 2. **SameSite Cookies**
177
+ ```
178
+ Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly
179
+ ```
180
+ - `Strict`: Cookie never sent cross-site (best security)
181
+ - `Lax`: Cookie sent on top-level navigations (good balance)
182
+ - Always combine with CSRF tokens for defense in depth
183
+
184
+ 3. **Double Submit Cookie Pattern**
185
+ - Send CSRF token in both cookie and request body/header
186
+ - Server validates they match
187
+
188
+ #### Edge Cases and Common Mistakes
189
+
190
+ - **Token presence check**: CSRF validation must NOT depend on whether the token is present, always require it
191
+ - **Token per form**: Consider unique tokens per form for sensitive operations
192
+ - **JSON APIs**: Don't assume JSON content-type prevents CSRF; validate Origin/Referer headers AND use tokens
193
+ - **CORS misconfiguration**: Overly permissive CORS can bypass SameSite cookies
194
+ - **Subdomains**: CSRF tokens should be scoped because subdomain takeover can lead to CSRF
195
+ - **Flash/PDF uploads**: Legacy browser plugins could bypass SameSite
196
+ - **GET requests with side effects**: Never perform state changes on GET
197
+ - **Token leakage**: Don't include CSRF tokens in URLs
198
+ - **Token in URL vs Header**: Prefer custom headers (X-CSRF-Token) over URL parameters
199
+
200
+
201
+ #### Verification Checklist
202
+
203
+ - [ ] Token is cryptographically random (use secure random generator)
204
+ - [ ] Token is tied to user session
205
+ - [ ] Token is validated server-side on all state-changing requests
206
+ - [ ] Missing token = rejected request
207
+ - [ ] Token regenerated on authentication state change
208
+ - [ ] SameSite cookie attribute is set
209
+ - [ ] Secure and HttpOnly flags on session cookies
210
+
211
+ ---
212
+
213
+ ### Secret Keys and Sensitive Data Exposure
214
+
215
+ No secrets or sensitive information should be accessible to client-side code.
216
+
217
+ #### Never Expose in Client-Side Code
218
+
219
+ **API Keys and Secrets:**
220
+ - Third-party API keys (Stripe, AWS, etc.)
221
+ - Database connection strings
222
+ - JWT signing secrets
223
+ - Encryption keys
224
+ - OAuth client secrets
225
+ - Internal service URLs/credentials
226
+
227
+ **Sensitive User Data:**
228
+ - Full credit card numbers
229
+ - Social Security Numbers
230
+ - Passwords (even hashed)
231
+ - Security questions/answers
232
+ - Full phone numbers (mask them: ***-***-1234)
233
+ - Sensitive PII that isn't needed for display
234
+
235
+ **Infrastructure Details:**
236
+ - Internal IP addresses
237
+ - Database schemas
238
+ - Debug information
239
+ - Stack traces in production
240
+ - Server software versions
241
+
242
+ #### Where Secrets Hide (Check These!)
243
+
244
+ - JavaScript bundles (including source maps)
245
+ - HTML comments
246
+ - Hidden form fields
247
+ - Data attributes
248
+ - LocalStorage/SessionStorage
249
+ - Initial state/hydration data in SSR apps
250
+ - Environment variables exposed via build tools (NEXT_PUBLIC_*, REACT_APP_*)
251
+
252
+ #### Best Practices
253
+
254
+ 1. **Environment Variables**: Store secrets in `.env` files
255
+ 2. **Server-Side Only**: Make API calls requiring secrets from backend only
256
+
257
+ ---
258
+
259
+ ## Open Redirect
260
+
261
+ Any endpoint accepting a URL for redirection must be protected against open redirect attacks.
262
+
263
+ ### Protection Strategies
264
+
265
+ 1. **Allowlist Validation**
266
+ ```
267
+ allowed_domains = ['yourdomain.com', 'app.yourdomain.com']
268
+
269
+ function isValidRedirect(url):
270
+ parsed = parseUrl(url)
271
+ return parsed.hostname in allowed_domains
272
+ ```
273
+
274
+ 2. **Relative URLs Only**
275
+ - Only accept paths (e.g., `/dashboard`) not full URLs
276
+ - Validate the path starts with `/` and doesn't contain `//`
277
+
278
+ 3. **Indirect References**
279
+ - Use a mapping instead of raw URLs: `?redirect=dashboard` → lookup to `/dashboard`
280
+
281
+ ### Bypass Techniques to Block
282
+
283
+ | Technique | Example | Why It Works |
284
+ |-----------|---------|--------------|
285
+ | @ symbol | `https://legit.com@evil.com` | Browser navigates to evil.com with legit.com as username |
286
+ | Subdomain abuse | `https://legit.com.evil.com` | evil.com owns the subdomain |
287
+ | Protocol tricks | `javascript:alert(1)` | XSS via redirect |
288
+ | Double URL encoding | `%252f%252fevil.com` | Decodes to `//evil.com` after double decode |
289
+ | Backslash | `https://legit.com\@evil.com` | Some parsers normalize `\` to `/` |
290
+ | Null byte | `https://legit.com%00.evil.com` | Some parsers truncate at null |
291
+ | Tab/newline | `https://legit.com%09.evil.com` | Whitespace confusion |
292
+ | Unicode normalization | `https://legіt.com` (Cyrillic і) | IDN homograph attack |
293
+ | Data URLs | `data:text/html,<script>...` | Direct payload execution |
294
+ | Protocol-relative | `//evil.com` | Uses current page's protocol |
295
+ | Fragment abuse | `https://legit.com#@evil.com` | Parsed differently by different libraries |
296
+
297
+ ### IDN Homograph Attack Protection
298
+
299
+ - Convert URLs to Punycode before validation
300
+ - Consider blocking non-ASCII domains entirely for sensitive redirects
301
+
302
+
303
+ ---
304
+
305
+ ### Password Security
306
+
307
+ #### Password Requirements
308
+
309
+ - Minimum 8 characters (12+ recommended)
310
+ - No maximum length (or very high, e.g., 128 chars)
311
+ - Allow all characters including special chars
312
+ - Don't require specific character types (let users choose strong passwords)
313
+
314
+ #### Storage
315
+
316
+ - Use Argon2id, bcrypt, or scrypt
317
+ - Never MD5, SHA1, or plain SHA256
318
+
319
+ ---
320
+
321
+ ## Server-Side Bugs
322
+
323
+ ### Server-Side Request Forgery (SSRF)
324
+
325
+ Any functionality where the server makes requests to URLs provided or influenced by users must be protected.
326
+
327
+ #### Potential Vulnerable Features
328
+
329
+ - Webhooks (user provides callback URL)
330
+ - URL previews
331
+ - PDF generators from URLs
332
+ - Image/file fetching from URLs
333
+ - Import from URL features
334
+ - RSS/feed readers
335
+ - API integrations with user-provided endpoints
336
+ - Proxy functionality
337
+ - HTML to PDF/image converters
338
+
339
+ #### Protection Strategies
340
+
341
+ 1. **Allowlist Approach** (Preferred)
342
+ - Only allow requests to pre-approved domains
343
+ - Maintain a strict allowlist for integrations
344
+
345
+ 2. **Network Segmentation**
346
+ - Run URL-fetching services in isolated network
347
+ - Block access to internal network, cloud metadata
348
+
349
+ #### IP and DNS Bypass Techniques to Block
350
+
351
+ | Technique | Example | Description |
352
+ |-----------|---------|-------------|
353
+ | Decimal IP | `http://2130706433` | 127.0.0.1 as decimal |
354
+ | Octal IP | `http://0177.0.0.1` | Octal representation |
355
+ | Hex IP | `http://0x7f.0x0.0x0.0x1` | Hexadecimal |
356
+ | IPv6 localhost | `http://[::1]` | IPv6 loopback |
357
+ | IPv6 mapped IPv4 | `http://[::ffff:127.0.0.1]` | IPv4-mapped IPv6 |
358
+ | Short IPv6 | `http://[::]` | All zeros |
359
+ | DNS rebinding | Attacker's DNS returns internal IP | First request resolves to external IP, second to internal |
360
+ | CNAME to internal | Attacker domain CNAMEs to internal | DNS points to internal hostname |
361
+ | URL parser confusion | `http://attacker.com#@internal` | Different parsing behaviors |
362
+ | Redirect chains | External URL redirects to internal | Follow redirects carefully |
363
+ | IPv6 scope ID | `http://[fe80::1%25eth0]` | Interface-scoped IPv6 |
364
+ | Rare IP formats | `http://127.1` | Shortened IP notation |
365
+
366
+ #### DNS Rebinding Prevention
367
+
368
+ 1. Resolve DNS before making request
369
+ 2. Validate resolved IP is not internal
370
+ 3. Pin the resolved IP for the request (don't re-resolve)
371
+ 4. Or: Resolve twice with delay, ensure both resolve to same external IP
372
+
373
+ #### Cloud Metadata Protection
374
+
375
+ Block access to cloud metadata endpoints:
376
+ - AWS: `169.254.169.254`
377
+ - GCP: `metadata.google.internal`, `169.254.169.254`, `http://metadata`
378
+ - Azure: `169.254.169.254`
379
+ - DigitalOcean: `169.254.169.254`
380
+
381
+ #### Implementation Checklist
382
+
383
+ - [ ] Validate URL scheme is HTTP/HTTPS only
384
+ - [ ] Resolve DNS and validate IP is not private/internal
385
+ - [ ] Block cloud metadata IPs explicitly
386
+ - [ ] Limit or disable redirect following
387
+ - [ ] If following redirects, validate each hop
388
+ - [ ] Set timeout on requests
389
+ - [ ] Limit response size
390
+ - [ ] Use network isolation where possible
391
+
392
+ ---
393
+
394
+ ### Insecure File Upload
395
+
396
+ File uploads must validate type, content, and size to prevent various attacks.
397
+
398
+ #### Validation Requirements
399
+
400
+ **1. File Type Validation**
401
+ - Check file extension against allowlist
402
+ - Validate magic bytes/file signature match expected type
403
+ - Never rely on just one check
404
+
405
+ **2. File Content Validation**
406
+ - Read and verify magic bytes
407
+ - For images: attempt to process with image library (detects malformed files)
408
+ - For documents: scan for macros, embedded objects
409
+ - Check for polyglot files (files valid as multiple types)
410
+
411
+ **3. File Size Limits**
412
+ - Set maximum file size server-side
413
+ - Configure web server/proxy limits as well
414
+ - Consider per-file-type limits (images smaller than videos)
415
+
416
+ #### Common Bypasses and Attacks
417
+
418
+ | Attack | Description | Prevention |
419
+ |--------|-------------|------------|
420
+ | Extension bypass | `shell.php.jpg` | Check full extension, use allowlist |
421
+ | Null byte | `shell.php%00.jpg` | Sanitize filename, check for null bytes |
422
+ | Double extension | `shell.jpg.php` | Only allow single extension |
423
+ | MIME type spoofing | Set Content-Type to image/jpeg | Validate magic bytes |
424
+ | Magic byte injection | Prepend valid magic bytes to malicious file | Check entire file structure, not just header |
425
+ | Polyglot files | File valid as both JPEG and JavaScript | Parse file as expected type, reject if invalid |
426
+ | SVG with JavaScript | `<svg onload="alert(1)">` | Sanitize SVG or disallow entirely |
427
+ | XXE via file upload | Malicious DOCX, XLSX (which are XML) | Disable external entities in parser |
428
+ | ZIP slip | `../../../etc/passwd` in archive | Validate extracted paths |
429
+ | ImageMagick exploits | Specially crafted images | Keep ImageMagick updated, use policy.xml |
430
+ | Filename injection | `; rm -rf /` in filename | Sanitize filenames, use random names |
431
+ | Content-type confusion | Browser MIME sniffing | Set `X-Content-Type-Options: nosniff` |
432
+
433
+ #### Magic Bytes Reference
434
+
435
+ | Type | Magic Bytes (hex) |
436
+ |------|-------------------|
437
+ | JPEG | `FF D8 FF` |
438
+ | PNG | `89 50 4E 47 0D 0A 1A 0A` |
439
+ | GIF | `47 49 46 38` |
440
+ | PDF | `25 50 44 46` |
441
+ | ZIP | `50 4B 03 04` |
442
+ | DOCX/XLSX | `50 4B 03 04` (ZIP-based) |
443
+
444
+ #### Secure Upload Handling
445
+
446
+ 1. **Rename files**: Use random UUID names, discard original
447
+ 2. **Store outside webroot**: Or use separate domain for uploads
448
+ 3. **Serve with correct headers**:
449
+ - `Content-Disposition: attachment` (forces download)
450
+ - `X-Content-Type-Options: nosniff`
451
+ - `Content-Type` matching actual file type
452
+ 4. **Use CDN/separate domain**: Isolate uploaded content from main app
453
+ 5. **Set restrictive permissions**: Uploaded files should not be executable
454
+
455
+ ---
456
+
457
+ ### SQL Injection
458
+
459
+ SQL injection occurs when user input is incorporated into SQL queries without proper handling.
460
+
461
+ #### Prevention Methods
462
+
463
+ **1. Parameterized Queries (Prepared Statements)** — PRIMARY DEFENSE
464
+ ```sql
465
+ -- VULNERABLE
466
+ query = "SELECT * FROM users WHERE id = " + userId
467
+
468
+ -- SECURE
469
+ query = "SELECT * FROM users WHERE id = ?"
470
+ execute(query, [userId])
471
+ ```
472
+
473
+ **2. ORM Usage**
474
+ - Use ORM methods that automatically parameterize
475
+ - Be cautious with raw query methods in ORMs
476
+ - Watch for ORM-specific injection points
477
+
478
+ **3. Input Validation**
479
+ - Validate data types (integer should be integer)
480
+ - Whitelist allowed values where applicable
481
+ - This is defense-in-depth, not primary defense
482
+
483
+ #### Injection Points to Watch
484
+
485
+ - WHERE clauses
486
+ - ORDER BY clauses (often overlooked—can't use parameters, must whitelist)
487
+ - LIMIT/OFFSET values
488
+ - Table and column names (can't parameterize—must whitelist)
489
+ - INSERT values
490
+ - UPDATE SET values
491
+ - IN clauses with dynamic lists
492
+ - LIKE patterns (also escape wildcards: %, _)
493
+
494
+ #### Additional Defenses
495
+
496
+ - **Least privilege**: Database user should have minimum required permissions
497
+ - **Disable dangerous functions**: Like `xp_cmdshell` in SQL Server
498
+ - **Error handling**: Never expose SQL errors to users
499
+
500
+ ---
501
+
502
+ ### XML External Entity (XXE)
503
+
504
+ XXE vulnerabilities occur when XML parsers process external entity references in user-supplied XML.
505
+
506
+ #### Vulnerable Scenarios
507
+
508
+ **Direct XML Input:**
509
+ - SOAP APIs
510
+ - XML-RPC
511
+ - XML file uploads
512
+ - Configuration file parsing
513
+ - RSS/Atom feed processing
514
+
515
+ **Indirect XML:**
516
+ - JSON/other format converted to XML server-side
517
+ - Office documents (DOCX, XLSX, PPTX are ZIP with XML)
518
+ - SVG files (XML-based)
519
+ - SAML assertions
520
+ - PDF with XFA forms
521
+
522
+
523
+ #### Prevention by Language/Parser
524
+
525
+ **Java:**
526
+ ```java
527
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
528
+ dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
529
+ dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
530
+ dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
531
+ dbf.setExpandEntityReferences(false);
532
+ ```
533
+
534
+ **Python (lxml):**
535
+ ```python
536
+ from lxml import etree
537
+ parser = etree.XMLParser(resolve_entities=False, no_network=True)
538
+ # Or use defusedxml library
539
+ ```
540
+
541
+ **PHP:**
542
+ ```php
543
+ libxml_disable_entity_loader(true);
544
+ // Or use XMLReader with proper settings
545
+ ```
546
+
547
+ **Node.js:**
548
+ ```javascript
549
+ // Use libraries that disable DTD processing by default
550
+ // If using libxmljs, set { noent: false, dtdload: false }
551
+ ```
552
+
553
+ **.NET:**
554
+ ```csharp
555
+ XmlReaderSettings settings = new XmlReaderSettings();
556
+ settings.DtdProcessing = DtdProcessing.Prohibit;
557
+ settings.XmlResolver = null;
558
+ ```
559
+
560
+ #### XXE Prevention Checklist
561
+
562
+ - [ ] Disable DTD processing entirely if possible
563
+ - [ ] Disable external entity resolution
564
+ - [ ] Disable external DTD loading
565
+ - [ ] Disable XInclude processing
566
+ - [ ] Use latest patched XML parser versions
567
+ - [ ] Validate/sanitize XML before parsing if DTD needed
568
+ - [ ] Consider using JSON instead of XML where possible
569
+
570
+ ---
571
+
572
+ ### Path Traversal
573
+
574
+ Path traversal vulnerabilities occur when user input controls file paths, allowing access to files outside intended directories.
575
+
576
+ #### Vulnerable Patterns
577
+
578
+ ```python
579
+ # VULNERABLE
580
+ file_path = "/uploads/" + user_input
581
+ file_path = base_dir + request.params['file']
582
+ template = "templates/" + user_provided_template
583
+ ```
584
+
585
+ #### Prevention Strategies
586
+
587
+ **1. Avoid User Input in Paths**
588
+ ```python
589
+ # Instead of using user input directly
590
+ # Use indirect references
591
+ files = {'report': '/reports/q1.pdf', 'invoice': '/invoices/2024.pdf'}
592
+ file_path = files.get(user_input) # Returns None if invalid
593
+ ```
594
+
595
+ **2. Canonicalization and Validation**
596
+
597
+ ```python
598
+ import os
599
+
600
+ def safe_join(base_directory, user_path):
601
+ # Ensure base is absolute and normalized
602
+ base = os.path.abspath(os.path.realpath(base_directory))
603
+
604
+ # Join and then resolve the result
605
+ target = os.path.abspath(os.path.realpath(os.path.join(base, user_path)))
606
+
607
+ # Ensure the commonpath is the base directory
608
+ if os.path.commonpath([base, target]) != base:
609
+ raise ValueError("Error!")
610
+
611
+ return target
612
+ ```
613
+
614
+ **3. Input Sanitization**
615
+ - Remove or reject `..` sequences
616
+ - Remove or reject absolute path indicators (`/`, `C:`)
617
+ - Whitelist allowed characters (alphanumeric, dash, underscore)
618
+ - Validate file extension if applicable
619
+
620
+
621
+ #### Path Traversal Checklist
622
+
623
+ - [ ] Never use user input directly in file paths
624
+ - [ ] Canonicalize paths and validate against base directory
625
+ - [ ] Restrict file extensions if applicable
626
+ - [ ] Test with various encoding and bypass techniques
627
+
628
+ ---
629
+
630
+ ## Security Headers Checklist
631
+
632
+ Include these headers in all responses:
633
+
634
+ ```
635
+ Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
636
+ Content-Security-Policy: [see XSS section]
637
+ X-Content-Type-Options: nosniff
638
+ X-Frame-Options: DENY
639
+ Referrer-Policy: strict-origin-when-cross-origin
640
+ Cache-Control: no-store (for sensitive pages)
641
+ ```
642
+
643
+ ---
644
+
645
+ ## JWT Security
646
+
647
+ JWT misconfigurations can lead to full authentication bypass and token forgery.
648
+
649
+ ### Vulnerabilities
650
+
651
+ | Vulnerability | Prevention |
652
+ |---------------|------------|
653
+ | `alg: none` attack | Always verify algorithm server-side, reject `none` |
654
+ | Algorithm confusion | Explicitly specify expected algorithm, never derive from token |
655
+ | Weak HMAC secrets | Use 256+ bit cryptographically random secrets |
656
+ | Missing expiration | Always set `exp` claim |
657
+ | Token in localStorage | Store in httpOnly, Secure, SameSite=Strict cookies, never localStorage |
658
+
659
+
660
+ ### Secure Implementation
661
+
662
+ ```javascript
663
+ // 1. SIGNING
664
+ // Always use environment variables for secrets
665
+ const secret = process.env.JWT_SECRET;
666
+
667
+ const token = jwt.sign({
668
+ sub: userId,
669
+ iat: Math.floor(Date.now() / 1000),
670
+ exp: Math.floor(Date.now() / 1000) + (15 * 60), // 15 mins (Short-lived)
671
+ jti: crypto.randomUUID() // Unique ID for revocation/blacklisting
672
+ }, secret, {
673
+ algorithm: 'HS256'
674
+ });
675
+
676
+ // 2. SENDING (Cookie Best Practices)
677
+ // Protect against XSS and CSRF
678
+ res.cookie('token', token, {
679
+ httpOnly: true,
680
+ secure: true,
681
+ sameSite: 'strict'
682
+ });
683
+
684
+ // 3. VERIFYING
685
+ // CRITICAL: Whitelist the allowed algorithm
686
+ jwt.verify(token, secret, { algorithms: ['HS256'] }, (err, decoded) => {
687
+ if (err) {
688
+ // Handle invalid token
689
+ }
690
+ // Trust the payload
691
+ });
692
+ ```
693
+
694
+ ### JWT Checklist
695
+
696
+ - [ ] Algorithm explicitly specified on verification (never trust token header)
697
+ - [ ] `alg: none` rejected
698
+ - [ ] Secret is 256+ bits of random data (not a password or phrase)
699
+ - [ ] `exp` claim always set and validated
700
+ - [ ] Tokens stored in httpOnly cookies (not localStorage/sessionStorage)
701
+ - [ ] Refresh token rotation implemented (old refresh token invalidated on use)
702
+
703
+ ---
704
+
705
+ ## API Security
706
+
707
+ ### Mass Assignment
708
+
709
+ Accepting unfiltered request bodies can lead to privilege escalation.
710
+
711
+ ```javascript
712
+ // VULNERABLE — user can set { role: "admin" } in request body
713
+ User.update(req.body)
714
+
715
+ // SECURE — whitelist allowed fields
716
+ const allowed = ['name', 'email', 'avatar']
717
+ const updates = pick(req.body, allowed)
718
+ User.update(updates)
719
+ ```
720
+
721
+ This applies to any ORM/framework — always explicitly define which fields a request can modify.
722
+
723
+ ### GraphQL
724
+
725
+ | Vulnerability | Prevention |
726
+ | :--- | :--- |
727
+ | Introspection in production | Disable introspection in production environments. |
728
+ | Query depth attack | Implement query depth limiting (e.g., maximum of 10 levels). |
729
+ | Query complexity attack | Calculate and enforce strict query cost limits. |
730
+ | Batching attack | Limit the number of operations allowed per single request. |
731
+
732
+
733
+ ```javascript
734
+ const server = new ApolloServer({
735
+ introspection: process.env.NODE_ENV !== 'production',
736
+ validationRules: [
737
+ depthLimit(10),
738
+ costAnalysis({ maximumCost: 1000 })
739
+ ]
740
+ })
741
+ ```
742
+
743
+ ---
744
+
745
+ ## General Security Principles
746
+
747
+ When generating code, always:
748
+
749
+ 1. **Validate all input server-side** — Never trust client-side validation alone
750
+ 2. **Use parameterized queries** — Never concatenate user input into queries
751
+ 3. **Encode output contextually** — HTML, JS, URL, CSS contexts need different encoding
752
+ 4. **Apply authentication checks** — On every endpoint, not just at routing
753
+ 5. **Apply authorization checks** — Verify the user can access the specific resource
754
+ 6. **Use secure defaults**
755
+ 7. **Handle errors securely** — Don't leak stack traces or internal details to users
756
+ 8. **Keep dependencies updated** — Use tools to track vulnerable dependencies
757
+
758
+ When unsure, choose the more restrictive/secure option and document the security consideration in comments.