opencode-metis 0.1.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.
Files changed (156) hide show
  1. package/README.md +140 -0
  2. package/dist/cli.cjs +63 -0
  3. package/dist/mcp-server.cjs +51 -0
  4. package/dist/plugin.cjs +4 -0
  5. package/dist/worker.cjs +224 -0
  6. package/opencode/agent/the-analyst/feature-prioritization.md +66 -0
  7. package/opencode/agent/the-analyst/market-research.md +77 -0
  8. package/opencode/agent/the-analyst/project-coordination.md +81 -0
  9. package/opencode/agent/the-analyst/requirements-analysis.md +77 -0
  10. package/opencode/agent/the-architect/compatibility-review.md +138 -0
  11. package/opencode/agent/the-architect/complexity-review.md +137 -0
  12. package/opencode/agent/the-architect/quality-review.md +67 -0
  13. package/opencode/agent/the-architect/security-review.md +127 -0
  14. package/opencode/agent/the-architect/system-architecture.md +119 -0
  15. package/opencode/agent/the-architect/system-documentation.md +83 -0
  16. package/opencode/agent/the-architect/technology-research.md +85 -0
  17. package/opencode/agent/the-chief.md +79 -0
  18. package/opencode/agent/the-designer/accessibility-implementation.md +101 -0
  19. package/opencode/agent/the-designer/design-foundation.md +74 -0
  20. package/opencode/agent/the-designer/interaction-architecture.md +75 -0
  21. package/opencode/agent/the-designer/user-research.md +70 -0
  22. package/opencode/agent/the-meta-agent.md +155 -0
  23. package/opencode/agent/the-platform-engineer/ci-cd-pipelines.md +109 -0
  24. package/opencode/agent/the-platform-engineer/containerization.md +106 -0
  25. package/opencode/agent/the-platform-engineer/data-architecture.md +81 -0
  26. package/opencode/agent/the-platform-engineer/dependency-review.md +144 -0
  27. package/opencode/agent/the-platform-engineer/deployment-automation.md +81 -0
  28. package/opencode/agent/the-platform-engineer/infrastructure-as-code.md +107 -0
  29. package/opencode/agent/the-platform-engineer/performance-tuning.md +82 -0
  30. package/opencode/agent/the-platform-engineer/pipeline-engineering.md +81 -0
  31. package/opencode/agent/the-platform-engineer/production-monitoring.md +105 -0
  32. package/opencode/agent/the-qa-engineer/exploratory-testing.md +66 -0
  33. package/opencode/agent/the-qa-engineer/performance-testing.md +81 -0
  34. package/opencode/agent/the-qa-engineer/quality-assurance.md +77 -0
  35. package/opencode/agent/the-qa-engineer/test-execution.md +66 -0
  36. package/opencode/agent/the-software-engineer/api-development.md +78 -0
  37. package/opencode/agent/the-software-engineer/component-development.md +79 -0
  38. package/opencode/agent/the-software-engineer/concurrency-review.md +141 -0
  39. package/opencode/agent/the-software-engineer/domain-modeling.md +66 -0
  40. package/opencode/agent/the-software-engineer/performance-optimization.md +113 -0
  41. package/opencode/command/analyze.md +149 -0
  42. package/opencode/command/constitution.md +178 -0
  43. package/opencode/command/debug.md +194 -0
  44. package/opencode/command/document.md +178 -0
  45. package/opencode/command/implement.md +225 -0
  46. package/opencode/command/refactor.md +207 -0
  47. package/opencode/command/review.md +229 -0
  48. package/opencode/command/simplify.md +267 -0
  49. package/opencode/command/specify.md +191 -0
  50. package/opencode/command/validate.md +224 -0
  51. package/opencode/skill/accessibility-design/SKILL.md +566 -0
  52. package/opencode/skill/accessibility-design/checklists/wcag-checklist.md +435 -0
  53. package/opencode/skill/agent-coordination/SKILL.md +224 -0
  54. package/opencode/skill/api-contract-design/SKILL.md +550 -0
  55. package/opencode/skill/api-contract-design/templates/graphql-schema-template.md +818 -0
  56. package/opencode/skill/api-contract-design/templates/rest-api-template.md +417 -0
  57. package/opencode/skill/architecture-design/SKILL.md +160 -0
  58. package/opencode/skill/architecture-design/examples/architecture-examples.md +170 -0
  59. package/opencode/skill/architecture-design/template.md +749 -0
  60. package/opencode/skill/architecture-design/validation.md +99 -0
  61. package/opencode/skill/architecture-selection/SKILL.md +522 -0
  62. package/opencode/skill/architecture-selection/examples/adrs/001-example-adr.md +71 -0
  63. package/opencode/skill/architecture-selection/examples/architecture-patterns.md +239 -0
  64. package/opencode/skill/bug-diagnosis/SKILL.md +235 -0
  65. package/opencode/skill/code-quality-review/SKILL.md +337 -0
  66. package/opencode/skill/code-quality-review/examples/anti-patterns.md +629 -0
  67. package/opencode/skill/code-quality-review/reference.md +322 -0
  68. package/opencode/skill/code-review/SKILL.md +363 -0
  69. package/opencode/skill/code-review/reference.md +450 -0
  70. package/opencode/skill/codebase-analysis/SKILL.md +139 -0
  71. package/opencode/skill/codebase-navigation/SKILL.md +227 -0
  72. package/opencode/skill/codebase-navigation/examples/exploration-patterns.md +263 -0
  73. package/opencode/skill/coding-conventions/SKILL.md +178 -0
  74. package/opencode/skill/coding-conventions/checklists/accessibility-checklist.md +176 -0
  75. package/opencode/skill/coding-conventions/checklists/performance-checklist.md +154 -0
  76. package/opencode/skill/coding-conventions/checklists/security-checklist.md +127 -0
  77. package/opencode/skill/constitution-validation/SKILL.md +315 -0
  78. package/opencode/skill/constitution-validation/examples/CONSTITUTION.md +202 -0
  79. package/opencode/skill/constitution-validation/reference/rule-patterns.md +328 -0
  80. package/opencode/skill/constitution-validation/template.md +115 -0
  81. package/opencode/skill/context-preservation/SKILL.md +445 -0
  82. package/opencode/skill/data-modeling/SKILL.md +385 -0
  83. package/opencode/skill/data-modeling/templates/schema-design-template.md +268 -0
  84. package/opencode/skill/deployment-pipeline-design/SKILL.md +579 -0
  85. package/opencode/skill/deployment-pipeline-design/templates/pipeline-template.md +633 -0
  86. package/opencode/skill/documentation-extraction/SKILL.md +259 -0
  87. package/opencode/skill/documentation-sync/SKILL.md +431 -0
  88. package/opencode/skill/domain-driven-design/SKILL.md +509 -0
  89. package/opencode/skill/domain-driven-design/examples/ddd-patterns.md +688 -0
  90. package/opencode/skill/domain-driven-design/reference.md +465 -0
  91. package/opencode/skill/drift-detection/SKILL.md +383 -0
  92. package/opencode/skill/drift-detection/reference.md +340 -0
  93. package/opencode/skill/error-recovery/SKILL.md +162 -0
  94. package/opencode/skill/error-recovery/examples/error-patterns.md +484 -0
  95. package/opencode/skill/feature-prioritization/SKILL.md +419 -0
  96. package/opencode/skill/feature-prioritization/examples/rice-template.md +139 -0
  97. package/opencode/skill/feature-prioritization/reference.md +256 -0
  98. package/opencode/skill/git-workflow/SKILL.md +453 -0
  99. package/opencode/skill/implementation-planning/SKILL.md +215 -0
  100. package/opencode/skill/implementation-planning/examples/phase-examples.md +217 -0
  101. package/opencode/skill/implementation-planning/template.md +220 -0
  102. package/opencode/skill/implementation-planning/validation.md +88 -0
  103. package/opencode/skill/implementation-verification/SKILL.md +272 -0
  104. package/opencode/skill/knowledge-capture/SKILL.md +265 -0
  105. package/opencode/skill/knowledge-capture/reference/knowledge-capture.md +402 -0
  106. package/opencode/skill/knowledge-capture/reference.md +444 -0
  107. package/opencode/skill/knowledge-capture/templates/domain-template.md +325 -0
  108. package/opencode/skill/knowledge-capture/templates/interface-template.md +255 -0
  109. package/opencode/skill/knowledge-capture/templates/pattern-template.md +144 -0
  110. package/opencode/skill/observability-design/SKILL.md +291 -0
  111. package/opencode/skill/observability-design/references/monitoring-patterns.md +461 -0
  112. package/opencode/skill/pattern-detection/SKILL.md +171 -0
  113. package/opencode/skill/pattern-detection/examples/common-patterns.md +359 -0
  114. package/opencode/skill/performance-analysis/SKILL.md +266 -0
  115. package/opencode/skill/performance-analysis/references/profiling-tools.md +499 -0
  116. package/opencode/skill/requirements-analysis/SKILL.md +139 -0
  117. package/opencode/skill/requirements-analysis/examples/good-prd.md +66 -0
  118. package/opencode/skill/requirements-analysis/template.md +177 -0
  119. package/opencode/skill/requirements-analysis/validation.md +69 -0
  120. package/opencode/skill/requirements-elicitation/SKILL.md +518 -0
  121. package/opencode/skill/requirements-elicitation/examples/interview-questions.md +226 -0
  122. package/opencode/skill/requirements-elicitation/examples/user-stories.md +414 -0
  123. package/opencode/skill/safe-refactoring/SKILL.md +312 -0
  124. package/opencode/skill/safe-refactoring/reference/code-smells.md +347 -0
  125. package/opencode/skill/security-assessment/SKILL.md +421 -0
  126. package/opencode/skill/security-assessment/checklists/security-review-checklist.md +285 -0
  127. package/opencode/skill/specification-management/SKILL.md +143 -0
  128. package/opencode/skill/specification-management/readme-template.md +32 -0
  129. package/opencode/skill/specification-management/reference.md +115 -0
  130. package/opencode/skill/specification-management/spec.py +229 -0
  131. package/opencode/skill/specification-validation/SKILL.md +397 -0
  132. package/opencode/skill/specification-validation/reference/3cs-framework.md +306 -0
  133. package/opencode/skill/specification-validation/reference/ambiguity-detection.md +132 -0
  134. package/opencode/skill/specification-validation/reference/constitution-validation.md +301 -0
  135. package/opencode/skill/specification-validation/reference/drift-detection.md +383 -0
  136. package/opencode/skill/task-delegation/SKILL.md +607 -0
  137. package/opencode/skill/task-delegation/examples/file-coordination.md +495 -0
  138. package/opencode/skill/task-delegation/examples/parallel-research.md +337 -0
  139. package/opencode/skill/task-delegation/examples/sequential-build.md +504 -0
  140. package/opencode/skill/task-delegation/reference.md +825 -0
  141. package/opencode/skill/tech-stack-detection/SKILL.md +89 -0
  142. package/opencode/skill/tech-stack-detection/references/framework-signatures.md +598 -0
  143. package/opencode/skill/technical-writing/SKILL.md +190 -0
  144. package/opencode/skill/technical-writing/templates/adr-template.md +205 -0
  145. package/opencode/skill/technical-writing/templates/system-doc-template.md +380 -0
  146. package/opencode/skill/test-design/SKILL.md +464 -0
  147. package/opencode/skill/test-design/examples/test-pyramid.md +724 -0
  148. package/opencode/skill/testing/SKILL.md +213 -0
  149. package/opencode/skill/testing/examples/test-pyramid.md +724 -0
  150. package/opencode/skill/user-insight-synthesis/SKILL.md +576 -0
  151. package/opencode/skill/user-insight-synthesis/templates/research-plan-template.md +217 -0
  152. package/opencode/skill/user-research/SKILL.md +508 -0
  153. package/opencode/skill/user-research/examples/interview-questions.md +265 -0
  154. package/opencode/skill/user-research/examples/personas.md +267 -0
  155. package/opencode/skill/vibe-security/SKILL.md +654 -0
  156. package/package.json +45 -0
@@ -0,0 +1,654 @@
1
+ ---
2
+ name: vibe-security
3
+ description: Write secure web applications following security best practices. Use when working on any web application to ensure OWASP compliance, input validation, authentication, and protection against XSS, CSRF, SSRF, and injection attacks.
4
+ license: MIT
5
+ compatibility: opencode
6
+ metadata:
7
+ category: development
8
+ version: "1.0"
9
+ ---
10
+
11
+ # Secure Coding Guide for Web Applications
12
+
13
+ Roleplay as a security-focused developer who approaches code from a bug hunter's perspective to make applications as secure as possible without breaking functionality.
14
+
15
+ VibeSecurity {
16
+ Activation {
17
+ Building or reviewing web application code
18
+ Implementing authentication or authorization
19
+ Handling user input or file uploads
20
+ Working with URLs, redirects, or external requests
21
+ Implementing CRUD operations with user data
22
+ Writing API endpoints
23
+ }
24
+
25
+ Constraints {
26
+ 1. Defense in depth: Never rely on a single security control
27
+ 2. Fail securely: When something fails, fail closed (deny access)
28
+ 3. Least privilege: Grant minimum permissions necessary
29
+ 4. Input validation: Never trust user input, validate everything server-side
30
+ 5. Output encoding: Encode data appropriately for the context it's rendered in
31
+ }
32
+
33
+ AccessControlIssues {
34
+ CoreRequirements {
35
+ UserLevelAuthorization {
36
+ - Each user must only access/modify their own data
37
+ - No user should access data from other users or organizations
38
+ - Always verify ownership at the data layer, not just the route level
39
+ }
40
+
41
+ UseUUIDsInsteadOfSequentialIDs {
42
+ - Use UUIDv4 or similar non-guessable identifiers
43
+ - Exception: Only use sequential IDs if explicitly requested by user
44
+ }
45
+
46
+ AccountLifecycleHandling {
47
+ - When a user is removed from an organization: immediately revoke all access tokens and sessions
48
+ - When an account is deleted/deactivated: invalidate all active sessions and API keys
49
+ - Implement token revocation lists or short-lived tokens with refresh mechanisms
50
+ }
51
+ }
52
+
53
+ AuthorizationChecksChecklist {
54
+ - [ ] Verify user owns the resource on every request (don't trust client-side data)
55
+ - [ ] Check organization membership for multi-tenant apps
56
+ - [ ] Validate role permissions for role-based actions
57
+ - [ ] Re-validate permissions after any privilege change
58
+ - [ ] Check parent resource ownership (e.g., if accessing a comment, verify user owns the parent post)
59
+ }
60
+
61
+ CommonPitfallsToAvoid {
62
+ - IDOR (Insecure Direct Object Reference): Always verify the requesting user has permission to access the requested resource ID
63
+ - Privilege Escalation: Validate role changes server-side; never trust role info from client
64
+ - Horizontal Access: User A accessing User B's resources with the same privilege level
65
+ - Vertical Access: Regular user accessing admin functionality
66
+ - Mass Assignment: Filter which fields users can update; don't blindly accept all request body fields
67
+ }
68
+
69
+ ImplementationPattern {
70
+ ```
71
+ # Pseudocode for secure resource access
72
+ function getResource(resourceId, currentUser):
73
+ resource = database.find(resourceId)
74
+
75
+ if resource is null:
76
+ return 404 # Don't reveal if resource exists
77
+
78
+ if resource.ownerId != currentUser.id:
79
+ if not currentUser.hasOrgAccess(resource.orgId):
80
+ return 404 # Return 404, not 403, to prevent enumeration
81
+
82
+ return resource
83
+ ```
84
+ }
85
+ }
86
+
87
+ ClientSideBugs {
88
+ CrossSiteScripting {
89
+ InputSourcesToProtect {
90
+ DirectInputs:
91
+ - Form fields (email, name, bio, comments, etc.)
92
+ - Search queries
93
+ - File names during upload
94
+ - Rich text editors / WYSIWYG content
95
+
96
+ IndirectInputs:
97
+ - URL parameters and query strings
98
+ - URL fragments (hash values)
99
+ - HTTP headers used in the application (Referer, User-Agent if displayed)
100
+ - Data from third-party APIs displayed to users
101
+ - WebSocket messages
102
+ - postMessage data from iframes
103
+ - LocalStorage/SessionStorage values if rendered
104
+
105
+ OftenOverlooked:
106
+ - Error messages that reflect user input
107
+ - PDF/document generators that accept HTML
108
+ - Email templates with user data
109
+ - Log viewers in admin panels
110
+ - JSON responses rendered as HTML
111
+ - SVG file uploads (can contain JavaScript)
112
+ - Markdown rendering (if allowing HTML)
113
+ }
114
+
115
+ ProtectionStrategies {
116
+ OutputEncoding {
117
+ Context-Specific:
118
+ - HTML context: HTML entity encode (`<` -> `&lt;`)
119
+ - JavaScript context: JavaScript escape
120
+ - URL context: URL encode
121
+ - CSS context: CSS escape
122
+ - Use framework's built-in escaping (React's JSX, Vue's {{ }}, etc.)
123
+ }
124
+
125
+ ContentSecurityPolicy {
126
+ ```
127
+ Content-Security-Policy:
128
+ default-src 'self';
129
+ script-src 'self';
130
+ style-src 'self' 'unsafe-inline';
131
+ img-src 'self' data: https:;
132
+ font-src 'self';
133
+ connect-src 'self' https://api.yourdomain.com;
134
+ frame-ancestors 'none';
135
+ base-uri 'self';
136
+ form-action 'self';
137
+ ```
138
+
139
+ - Avoid `'unsafe-inline'` and `'unsafe-eval'` for scripts
140
+ - Use nonces or hashes for inline scripts when necessary
141
+ - Report violations: `report-uri /csp-report`
142
+ }
143
+
144
+ InputSanitization {
145
+ - Use established libraries (DOMPurify for HTML)
146
+ - Whitelist allowed tags/attributes for rich text
147
+ - Strip or encode dangerous patterns
148
+ }
149
+
150
+ AdditionalHeaders {
151
+ - `X-Content-Type-Options: nosniff`
152
+ - `X-Frame-Options: DENY` (or use CSP frame-ancestors)
153
+ }
154
+ }
155
+ }
156
+
157
+ CrossSiteRequestForgery {
158
+ EndpointsRequiringCSRFProtection {
159
+ AuthenticatedActions:
160
+ - All POST, PUT, PATCH, DELETE requests
161
+ - Any GET request that changes state (fix these to use proper HTTP methods)
162
+ - File uploads
163
+ - Settings changes
164
+ - Payment/transaction endpoints
165
+
166
+ PreAuthenticationActions:
167
+ - Login endpoints (prevent login CSRF)
168
+ - Signup endpoints
169
+ - Password reset request endpoints
170
+ - Password change endpoints
171
+ - Email/phone verification endpoints
172
+ - OAuth callback endpoints
173
+ }
174
+
175
+ ProtectionMechanisms {
176
+ CSRFTokens {
177
+ - Generate cryptographically random tokens
178
+ - Tie token to user session
179
+ - Validate on every state-changing request
180
+ - Regenerate after login (prevent session fixation combo)
181
+ }
182
+
183
+ SameSiteCookies {
184
+ ```
185
+ Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly
186
+ ```
187
+
188
+ - `Strict`: Cookie never sent cross-site (best security)
189
+ - `Lax`: Cookie sent on top-level navigations (good balance)
190
+ - Always combine with CSRF tokens for defense in depth
191
+ }
192
+
193
+ DoubleSubmitCookiePattern {
194
+ - Send CSRF token in both cookie and request body/header
195
+ - Server validates they match
196
+ }
197
+ }
198
+
199
+ EdgeCasesAndCommonMistakes {
200
+ - Token presence check: CSRF validation must NOT depend on whether the token is present, always require it
201
+ - Token per form: Consider unique tokens per form for sensitive operations
202
+ - JSON APIs: Don't assume JSON content-type prevents CSRF; validate Origin/Referer headers AND use tokens
203
+ - CORS misconfiguration: Overly permissive CORS can bypass SameSite cookies
204
+ - Subdomains: CSRF tokens should be scoped because subdomain takeover can lead to CSRF
205
+ - Flash/PDF uploads: Legacy browser plugins could bypass SameSite
206
+ - GET requests with side effects: Never perform state changes on GET
207
+ - Token leakage: Don't include CSRF tokens in URLs
208
+ - Token in URL vs Header: Prefer custom headers (X-CSRF-Token) over URL parameters
209
+ }
210
+
211
+ VerificationChecklist {
212
+ - [ ] Token is cryptographically random (use secure random generator)
213
+ - [ ] Token is tied to user session
214
+ - [ ] Token is validated server-side on all state-changing requests
215
+ - [ ] Missing token = rejected request
216
+ - [ ] Token regenerated on authentication state change
217
+ - [ ] SameSite cookie attribute is set
218
+ - [ ] Secure and HttpOnly flags on session cookies
219
+ }
220
+ }
221
+
222
+ SecretKeysAndSensitiveDataExposure {
223
+ NeverExposeInClientSideCode {
224
+ APIKeysAndSecrets:
225
+ - Third-party API keys (Stripe, AWS, etc.)
226
+ - Database connection strings
227
+ - JWT signing secrets
228
+ - Encryption keys
229
+ - OAuth client secrets
230
+ - Internal service URLs/credentials
231
+
232
+ SensitiveUserData:
233
+ - Full credit card numbers
234
+ - Social Security Numbers
235
+ - Passwords (even hashed)
236
+ - Security questions/answers
237
+ - Full phone numbers (mask them: ***-***-1234)
238
+ - Sensitive PII that isn't needed for display
239
+
240
+ InfrastructureDetails:
241
+ - Internal IP addresses
242
+ - Database schemas
243
+ - Debug information
244
+ - Stack traces in production
245
+ - Server software versions
246
+ }
247
+
248
+ WhereSecretsHide {
249
+ Check these locations:
250
+ - JavaScript bundles (including source maps)
251
+ - HTML comments
252
+ - Hidden form fields
253
+ - Data attributes
254
+ - LocalStorage/SessionStorage
255
+ - Initial state/hydration data in SSR apps
256
+ - Environment variables exposed via build tools (NEXT_PUBLIC_*, REACT_APP_*)
257
+ }
258
+
259
+ BestPractices {
260
+ - Environment Variables: Store secrets in `.env` files
261
+ - Server-Side Only: Make API calls requiring secrets from backend only
262
+ }
263
+ }
264
+ }
265
+
266
+ OpenRedirect {
267
+ ProtectionStrategies {
268
+ AllowlistValidation {
269
+ ```
270
+ allowed_domains = ['yourdomain.com', 'app.yourdomain.com']
271
+
272
+ function isValidRedirect(url):
273
+ parsed = parseUrl(url)
274
+ return parsed.hostname in allowed_domains
275
+ ```
276
+ }
277
+
278
+ RelativeURLsOnly {
279
+ - Only accept paths (e.g., `/dashboard`) not full URLs
280
+ - Validate the path starts with `/` and doesn't contain `//`
281
+ }
282
+
283
+ IndirectReferences {
284
+ - Use a mapping instead of raw URLs: `?redirect=dashboard` -> lookup to `/dashboard`
285
+ }
286
+ }
287
+
288
+ BypassTechniquesToBlock {
289
+ | Technique | Example | Why It Works |
290
+ | --------- | ------- | ------------ |
291
+ | @ symbol | `https://legit.com@evil.com` | Browser navigates to evil.com with legit.com as username |
292
+ | Subdomain abuse | `https://legit.com.evil.com` | evil.com owns the subdomain |
293
+ | Protocol tricks | `javascript:alert(1)` | XSS via redirect |
294
+ | Double URL encoding | `%252f%252fevil.com` | Decodes to `//evil.com` after double decode |
295
+ | Backslash | `https://legit.com\@evil.com` | Some parsers normalize `\` to `/` |
296
+ | Null byte | `https://legit.com%00.evil.com` | Some parsers truncate at null |
297
+ | Tab/newline | `https://legit.com%09.evil.com` | Whitespace confusion |
298
+ | Unicode normalization | `https://legіt.com` (Cyrillic і) | IDN homograph attack |
299
+ | Data URLs | `data:text/html,<script>...` | Direct payload execution |
300
+ | Protocol-relative | `//evil.com` | Uses current page's protocol |
301
+ | Fragment abuse | `https://legit.com#@evil.com` | Parsed differently by different libraries |
302
+ }
303
+
304
+ IDNHomographAttackProtection {
305
+ - Convert URLs to Punycode before validation
306
+ - Consider blocking non-ASCII domains entirely for sensitive redirects
307
+ }
308
+ }
309
+
310
+ PasswordSecurity {
311
+ PasswordRequirements {
312
+ - Minimum 8 characters (12+ recommended)
313
+ - No maximum length (or very high, e.g., 128 chars)
314
+ - Allow all characters including special chars
315
+ - Don't require specific character types (let users choose strong passwords)
316
+ }
317
+
318
+ Storage {
319
+ - Use Argon2id, bcrypt, or scrypt
320
+ - Never MD5, SHA1, or plain SHA256
321
+ }
322
+ }
323
+
324
+ ServerSideBugs {
325
+ ServerSideRequestForgery {
326
+ PotentialVulnerableFeatures {
327
+ - Webhooks (user provides callback URL)
328
+ - URL previews
329
+ - PDF generators from URLs
330
+ - Image/file fetching from URLs
331
+ - Import from URL features
332
+ - RSS/feed readers
333
+ - API integrations with user-provided endpoints
334
+ - Proxy functionality
335
+ - HTML to PDF/image converters
336
+ }
337
+
338
+ ProtectionStrategies {
339
+ AllowlistApproach {
340
+ Preferred:
341
+ - Only allow requests to pre-approved domains
342
+ - Maintain a strict allowlist for integrations
343
+ }
344
+
345
+ NetworkSegmentation {
346
+ - Run URL-fetching services in isolated network
347
+ - Block access to internal network, cloud metadata
348
+ }
349
+ }
350
+
351
+ IPAndDNSBypassTechniquesToBlock {
352
+ | Technique | Example | Description |
353
+ | --------- | ------- | ----------- |
354
+ | Decimal IP | `http://2130706433` | 127.0.0.1 as decimal |
355
+ | Octal IP | `http://0177.0.0.1` | Octal representation |
356
+ | Hex IP | `http://0x7f.0x0.0x0.0x1` | Hexadecimal |
357
+ | IPv6 localhost | `http://[::1]` | IPv6 loopback |
358
+ | IPv6 mapped IPv4 | `http://[::ffff:127.0.0.1]` | IPv4-mapped IPv6 |
359
+ | Short IPv6 | `http://[::]` | All zeros |
360
+ | DNS rebinding | Attacker's DNS returns internal IP | First request resolves to external IP, second to internal |
361
+ | CNAME to internal | Attacker domain CNAMEs to internal | DNS points to internal hostname |
362
+ | URL parser confusion | `http://attacker.com#@internal` | Different parsing behaviors |
363
+ | Redirect chains | External URL redirects to internal | Follow redirects carefully |
364
+ | IPv6 scope ID | `http://[fe80::1%25eth0]` | Interface-scoped IPv6 |
365
+ | Rare IP formats | `http://127.1` | Shortened IP notation |
366
+ }
367
+
368
+ DNSRebindingPrevention {
369
+ 1. Resolve DNS before making request
370
+ 2. Validate resolved IP is not internal
371
+ 3. Pin the resolved IP for the request (don't re-resolve)
372
+ 4. Or: Resolve twice with delay, ensure both resolve to same external IP
373
+ }
374
+
375
+ CloudMetadataProtection {
376
+ Block access to cloud metadata endpoints:
377
+ - AWS: `169.254.169.254`
378
+ - GCP: `metadata.google.internal`, `169.254.169.254`, `http://metadata`
379
+ - Azure: `169.254.169.254`
380
+ - DigitalOcean: `169.254.169.254`
381
+ }
382
+
383
+ ImplementationChecklist {
384
+ - [ ] Validate URL scheme is HTTP/HTTPS only
385
+ - [ ] Resolve DNS and validate IP is not private/internal
386
+ - [ ] Block cloud metadata IPs explicitly
387
+ - [ ] Limit or disable redirect following
388
+ - [ ] If following redirects, validate each hop
389
+ - [ ] Set timeout on requests
390
+ - [ ] Limit response size
391
+ - [ ] Use network isolation where possible
392
+ }
393
+ }
394
+
395
+ InsecureFileUpload {
396
+ ValidationRequirements {
397
+ FileTypeValidation {
398
+ - Check file extension against allowlist
399
+ - Validate magic bytes/file signature match expected type
400
+ - Never rely on just one check
401
+ }
402
+
403
+ FileContentValidation {
404
+ - Read and verify magic bytes
405
+ - For images: attempt to process with image library (detects malformed files)
406
+ - For documents: scan for macros, embedded objects
407
+ - Check for polyglot files (files valid as multiple types)
408
+ }
409
+
410
+ FileSizeLimits {
411
+ - Set maximum file size server-side
412
+ - Configure web server/proxy limits as well
413
+ - Consider per-file-type limits (images smaller than videos)
414
+ }
415
+ }
416
+
417
+ CommonBypassesAndAttacks {
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
+
434
+ MagicBytesReference {
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
+
445
+ SecureUploadHandling {
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
+ SQLInjection {
458
+ PreventionMethods {
459
+ ParameterizedQueries {
460
+ PRIMARY DEFENSE:
461
+ ```sql
462
+ -- VULNERABLE
463
+ query = "SELECT * FROM users WHERE id = " + userId
464
+
465
+ -- SECURE
466
+ query = "SELECT * FROM users WHERE id = ?"
467
+ execute(query, [userId])
468
+ ```
469
+ }
470
+
471
+ ORMUsage {
472
+ - Use ORM methods that automatically parameterize
473
+ - Be cautious with raw query methods in ORMs
474
+ - Watch for ORM-specific injection points
475
+ }
476
+
477
+ InputValidation {
478
+ - Validate data types (integer should be integer)
479
+ - Whitelist allowed values where applicable
480
+ - This is defense-in-depth, not primary defense
481
+ }
482
+ }
483
+
484
+ InjectionPointsToWatch {
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
+
495
+ AdditionalDefenses {
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
+ XMLExternalEntity {
503
+ VulnerableScenarios {
504
+ DirectXMLInput:
505
+ - SOAP APIs
506
+ - XML-RPC
507
+ - XML file uploads
508
+ - Configuration file parsing
509
+ - RSS/Atom feed processing
510
+
511
+ IndirectXML:
512
+ - JSON/other format converted to XML server-side
513
+ - Office documents (DOCX, XLSX, PPTX are ZIP with XML)
514
+ - SVG files (XML-based)
515
+ - SAML assertions
516
+ - PDF with XFA forms
517
+ }
518
+
519
+ PreventionByLanguage {
520
+ Java {
521
+ ```java
522
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
523
+ dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
524
+ dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
525
+ dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
526
+ dbf.setExpandEntityReferences(false);
527
+ ```
528
+ }
529
+
530
+ Python {
531
+ ```python
532
+ from lxml import etree
533
+ parser = etree.XMLParser(resolve_entities=False, no_network=True)
534
+ # Or use defusedxml library
535
+ ```
536
+ }
537
+
538
+ PHP {
539
+ ```php
540
+ libxml_disable_entity_loader(true);
541
+ // Or use XMLReader with proper settings
542
+ ```
543
+ }
544
+
545
+ NodeJS {
546
+ ```javascript
547
+ // Use libraries that disable DTD processing by default
548
+ // If using libxmljs, set { noent: false, dtdload: false }
549
+ ```
550
+ }
551
+
552
+ DotNet {
553
+ ```csharp
554
+ XmlReaderSettings settings = new XmlReaderSettings();
555
+ settings.DtdProcessing = DtdProcessing.Prohibit;
556
+ settings.XmlResolver = null;
557
+ ```
558
+ }
559
+ }
560
+
561
+ XXEPreventionChecklist {
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
+ PathTraversal {
573
+ VulnerablePatterns {
574
+ ```python
575
+ # VULNERABLE
576
+ file_path = "/uploads/" + user_input
577
+ file_path = base_dir + request.params['file']
578
+ template = "templates/" + user_provided_template
579
+ ```
580
+ }
581
+
582
+ PreventionStrategies {
583
+ AvoidUserInputInPaths {
584
+ ```python
585
+ # Instead of using user input directly
586
+ # Use indirect references
587
+ files = {'report': '/reports/q1.pdf', 'invoice': '/invoices/2024.pdf'}
588
+ file_path = files.get(user_input) # Returns None if invalid
589
+ ```
590
+ }
591
+
592
+ CanonicalizationAndValidation {
593
+ ```python
594
+ import os
595
+
596
+ def safe_join(base_directory, user_path):
597
+ # Ensure base is absolute and normalized
598
+ base = os.path.abspath(os.path.realpath(base_directory))
599
+
600
+ # Join and then resolve the result
601
+ target = os.path.abspath(os.path.realpath(os.path.join(base, user_path)))
602
+
603
+ # Ensure the commonpath is the base directory
604
+ if os.path.commonpath([base, target]) != base:
605
+ raise ValueError("Error!")
606
+
607
+ return target
608
+ ```
609
+ }
610
+
611
+ InputSanitization {
612
+ - Remove or reject `..` sequences
613
+ - Remove or reject absolute path indicators (`/`, `C:`)
614
+ - Whitelist allowed characters (alphanumeric, dash, underscore)
615
+ - Validate file extension if applicable
616
+ }
617
+ }
618
+
619
+ PathTraversalChecklist {
620
+ - [ ] Never use user input directly in file paths
621
+ - [ ] Canonicalize paths and validate against base directory
622
+ - [ ] Restrict file extensions if applicable
623
+ - [ ] Test with various encoding and bypass techniques
624
+ }
625
+ }
626
+ }
627
+
628
+ SecurityHeadersChecklist {
629
+ Include these headers in all responses:
630
+
631
+ ```
632
+ Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
633
+ Content-Security-Policy: [see XSS section]
634
+ X-Content-Type-Options: nosniff
635
+ X-Frame-Options: DENY
636
+ Referrer-Policy: strict-origin-when-cross-origin
637
+ Cache-Control: no-store (for sensitive pages)
638
+ ```
639
+ }
640
+
641
+ GeneralSecurityPrinciples {
642
+ When generating code, always:
643
+ 1. Validate all input server-side -- Never trust client-side validation alone
644
+ 2. Use parameterized queries -- Never concatenate user input into queries
645
+ 3. Encode output contextually -- HTML, JS, URL, CSS contexts need different encoding
646
+ 4. Apply authentication checks -- On every endpoint, not just at routing
647
+ 5. Apply authorization checks -- Verify the user can access the specific resource
648
+ 6. Use secure defaults
649
+ 7. Handle errors securely -- Don't leak stack traces or internal details to users
650
+ 8. Keep dependencies updated -- Use tools to track vulnerable dependencies
651
+
652
+ When unsure, choose the more restrictive/secure option and document the security consideration in comments.
653
+ }
654
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "opencode-metis",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Persistent memory system for OpenCode sessions",
6
+ "license": "MIT",
7
+ "engines": {
8
+ "bun": ">=1.0.0"
9
+ },
10
+ "main": "dist/plugin.cjs",
11
+ "exports": {
12
+ ".": "./dist/plugin.cjs",
13
+ "./worker": "./dist/worker.cjs",
14
+ "./mcp-server": "./dist/mcp-server.cjs"
15
+ },
16
+ "bin": {
17
+ "opencode-metis": "./dist/cli.cjs"
18
+ },
19
+ "files": [
20
+ "dist/",
21
+ "opencode/"
22
+ ],
23
+ "scripts": {
24
+ "test": "bun test",
25
+ "build": "bun run build.ts",
26
+ "lint": "eslint src --fix && prettier --write src",
27
+ "typecheck": "tsc --noEmit",
28
+ "dev": "bun run --watch src/cli/worker.ts",
29
+ "link": "mkdir -p ~/.config/opencode/plugins && stow --no-folding -d .stow -t ~/.config/opencode/plugins opencode-metis",
30
+ "unlink": "stow -d .stow -t ~/.config/opencode/plugins -D opencode-metis"
31
+ },
32
+ "dependencies": {
33
+ "@modelcontextprotocol/sdk": "^1.26.0",
34
+ "@xenova/transformers": "^2.17.0",
35
+ "chromadb": "^1.9.2",
36
+ "zod": "^3.23.8"
37
+ },
38
+ "devDependencies": {
39
+ "@types/bun": "latest",
40
+ "esbuild": "^0.27.2",
41
+ "eslint": "^9.0.0",
42
+ "prettier": "^3.0.0",
43
+ "typescript": "^5.3.0"
44
+ }
45
+ }