git-doc-mcp 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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +543 -0
  3. package/dist/audit/index.d.ts +2 -0
  4. package/dist/audit/index.d.ts.map +1 -0
  5. package/dist/audit/index.js +2 -0
  6. package/dist/audit/index.js.map +1 -0
  7. package/dist/audit/logger.d.ts +81 -0
  8. package/dist/audit/logger.d.ts.map +1 -0
  9. package/dist/audit/logger.js +179 -0
  10. package/dist/audit/logger.js.map +1 -0
  11. package/dist/cli/commands/serve.d.ts +44 -0
  12. package/dist/cli/commands/serve.d.ts.map +1 -0
  13. package/dist/cli/commands/serve.js +360 -0
  14. package/dist/cli/commands/serve.js.map +1 -0
  15. package/dist/cli/index.d.ts +21 -0
  16. package/dist/cli/index.d.ts.map +1 -0
  17. package/dist/cli/index.js +71 -0
  18. package/dist/cli/index.js.map +1 -0
  19. package/dist/http/client.d.ts +39 -0
  20. package/dist/http/client.d.ts.map +1 -0
  21. package/dist/http/client.js +114 -0
  22. package/dist/http/client.js.map +1 -0
  23. package/dist/http/index.d.ts +7 -0
  24. package/dist/http/index.d.ts.map +1 -0
  25. package/dist/http/index.js +7 -0
  26. package/dist/http/index.js.map +1 -0
  27. package/dist/http/redirect-utils.d.ts +27 -0
  28. package/dist/http/redirect-utils.d.ts.map +1 -0
  29. package/dist/http/redirect-utils.js +73 -0
  30. package/dist/http/redirect-utils.js.map +1 -0
  31. package/dist/index.d.ts +36 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +44 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/manifest/index.d.ts +7 -0
  36. package/dist/manifest/index.d.ts.map +1 -0
  37. package/dist/manifest/index.js +7 -0
  38. package/dist/manifest/index.js.map +1 -0
  39. package/dist/manifest/loader.d.ts +55 -0
  40. package/dist/manifest/loader.d.ts.map +1 -0
  41. package/dist/manifest/loader.js +222 -0
  42. package/dist/manifest/loader.js.map +1 -0
  43. package/dist/manifest/schema.d.ts +909 -0
  44. package/dist/manifest/schema.d.ts.map +1 -0
  45. package/dist/manifest/schema.js +148 -0
  46. package/dist/manifest/schema.js.map +1 -0
  47. package/dist/rate-limit/index.d.ts +6 -0
  48. package/dist/rate-limit/index.d.ts.map +1 -0
  49. package/dist/rate-limit/index.js +6 -0
  50. package/dist/rate-limit/index.js.map +1 -0
  51. package/dist/rate-limit/limiter.d.ts +38 -0
  52. package/dist/rate-limit/limiter.d.ts.map +1 -0
  53. package/dist/rate-limit/limiter.js +55 -0
  54. package/dist/rate-limit/limiter.js.map +1 -0
  55. package/dist/sandbox/context.d.ts +69 -0
  56. package/dist/sandbox/context.d.ts.map +1 -0
  57. package/dist/sandbox/context.js +134 -0
  58. package/dist/sandbox/context.js.map +1 -0
  59. package/dist/sandbox/executor.d.ts +50 -0
  60. package/dist/sandbox/executor.d.ts.map +1 -0
  61. package/dist/sandbox/executor.js +259 -0
  62. package/dist/sandbox/executor.js.map +1 -0
  63. package/dist/sandbox/index.d.ts +8 -0
  64. package/dist/sandbox/index.d.ts.map +1 -0
  65. package/dist/sandbox/index.js +8 -0
  66. package/dist/sandbox/index.js.map +1 -0
  67. package/dist/sandbox/url-validator.d.ts +40 -0
  68. package/dist/sandbox/url-validator.d.ts.map +1 -0
  69. package/dist/sandbox/url-validator.js +178 -0
  70. package/dist/sandbox/url-validator.js.map +1 -0
  71. package/dist/secrets/index.d.ts +7 -0
  72. package/dist/secrets/index.d.ts.map +1 -0
  73. package/dist/secrets/index.js +7 -0
  74. package/dist/secrets/index.js.map +1 -0
  75. package/dist/secrets/manager.d.ts +55 -0
  76. package/dist/secrets/manager.d.ts.map +1 -0
  77. package/dist/secrets/manager.js +94 -0
  78. package/dist/secrets/manager.js.map +1 -0
  79. package/dist/secrets/patterns.d.ts +33 -0
  80. package/dist/secrets/patterns.d.ts.map +1 -0
  81. package/dist/secrets/patterns.js +71 -0
  82. package/dist/secrets/patterns.js.map +1 -0
  83. package/dist/server/index.d.ts +6 -0
  84. package/dist/server/index.d.ts.map +1 -0
  85. package/dist/server/index.js +6 -0
  86. package/dist/server/index.js.map +1 -0
  87. package/dist/server/mcp.d.ts +60 -0
  88. package/dist/server/mcp.d.ts.map +1 -0
  89. package/dist/server/mcp.js +173 -0
  90. package/dist/server/mcp.js.map +1 -0
  91. package/dist/worker/index.d.ts +7 -0
  92. package/dist/worker/index.d.ts.map +1 -0
  93. package/dist/worker/index.js +7 -0
  94. package/dist/worker/index.js.map +1 -0
  95. package/dist/worker/process.d.ts +64 -0
  96. package/dist/worker/process.d.ts.map +1 -0
  97. package/dist/worker/process.js +222 -0
  98. package/dist/worker/process.js.map +1 -0
  99. package/dist/worker/protocol.d.ts +83 -0
  100. package/dist/worker/protocol.d.ts.map +1 -0
  101. package/dist/worker/protocol.js +55 -0
  102. package/dist/worker/protocol.js.map +1 -0
  103. package/dist/worker/worker-entry.d.ts +30 -0
  104. package/dist/worker/worker-entry.d.ts.map +1 -0
  105. package/dist/worker/worker-entry.js +136 -0
  106. package/dist/worker/worker-entry.js.map +1 -0
  107. package/package.json +55 -0
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Sandbox executor using isolated-vm.
3
+ * @module sandbox/executor
4
+ */
5
+ import ivm from 'isolated-vm';
6
+ import { createActionContext } from './context.js';
7
+ /**
8
+ * Default sandbox options.
9
+ */
10
+ const DEFAULT_SANDBOX_OPTIONS = {
11
+ memoryLimit: 128 * 1024 * 1024, // 128MB
12
+ cpuTimeLimit: 30000, // 30 seconds
13
+ wallTimeLimit: 60000, // 60 seconds
14
+ };
15
+ /**
16
+ * Result size limits.
17
+ */
18
+ const MAX_RESULT_SIZE = 1024 * 1024; // 1MB
19
+ const MAX_CONTENT_ITEMS = 100;
20
+ /**
21
+ * Validate and truncate result if too large.
22
+ */
23
+ export function validateResultSize(result) {
24
+ // Check content item count
25
+ if (result.content.length > MAX_CONTENT_ITEMS) {
26
+ return {
27
+ content: result.content.slice(0, MAX_CONTENT_ITEMS).concat([
28
+ { type: 'text', text: `[Truncated: ${result.content.length - MAX_CONTENT_ITEMS} more items]` }
29
+ ]),
30
+ isError: result.isError,
31
+ };
32
+ }
33
+ // Check total size
34
+ const serializedSize = JSON.stringify(result).length;
35
+ if (serializedSize > MAX_RESULT_SIZE) {
36
+ // Truncate text content
37
+ const truncatedContent = result.content.map(item => {
38
+ if (item.type === 'text' && item.text.length > 10000) {
39
+ return { type: 'text', text: item.text.slice(0, 10000) + '\n...[truncated]' };
40
+ }
41
+ return item;
42
+ });
43
+ return {
44
+ content: truncatedContent,
45
+ isError: result.isError,
46
+ };
47
+ }
48
+ return result;
49
+ }
50
+ /**
51
+ * Transform ES module action code to CommonJS-style for isolated-vm.
52
+ */
53
+ export function transformActionCode(code) {
54
+ // Handle `export default function name(...)` pattern
55
+ // export default async function echo(input, ctx) -> async function __default__(input, ctx)
56
+ let transformed = code.replace(/export\s+default\s+(async\s+)?function\s+\w+\s*\(/g, '$1function __default__(');
57
+ // Handle `export default function(...)` (anonymous) - unlikely but handle it
58
+ transformed = transformed.replace(/export\s+default\s+(async\s+)?function\s*\(/g, '$1function __default__(');
59
+ // Handle `export default (async function...)` expressions
60
+ transformed = transformed.replace(/export\s+default\s+\((async\s+)?function/g, '(__default__ = $1function');
61
+ // Handle `export default { ... }` objects or arrow functions
62
+ // export default async (input, ctx) => { ... }
63
+ if (!transformed.includes('function __default__')) {
64
+ // Check for arrow function export
65
+ const arrowMatch = code.match(/export\s+default\s+(async\s+)?\(([^)]*)\)\s*=>\s*/);
66
+ if (arrowMatch) {
67
+ const isAsync = arrowMatch[1] ? 'async ' : '';
68
+ const params = arrowMatch[2];
69
+ const matchEnd = arrowMatch.index + arrowMatch[0].length;
70
+ const afterArrow = code.slice(matchEnd);
71
+ if (afterArrow.trimStart().startsWith('{')) {
72
+ // Block body: export default async (input) => { ... } → async function __default__(input) { ... }
73
+ transformed = code.replace(/export\s+default\s+(async\s+)?\([^)]*\)\s*=>\s*/, `${isAsync}function __default__(${params}) `);
74
+ }
75
+ else {
76
+ // Expression body: export default (input) => expr; → function __default__(input) { return expr; }
77
+ const beforeExport = code.slice(0, arrowMatch.index);
78
+ const expr = afterArrow.replace(/;\s*$/, '');
79
+ transformed = beforeExport + `${isAsync}function __default__(${params}) { return ${expr}; }`;
80
+ }
81
+ }
82
+ else {
83
+ // Generic export default replacement
84
+ transformed = code.replace(/export\s+default\s+/g, 'const __default__ = ');
85
+ }
86
+ }
87
+ // Remove other exports (they're not needed for action execution)
88
+ transformed = transformed.replace(/export\s+\{[^}]*\}/g, '');
89
+ transformed = transformed.replace(/export\s+(const|let|var|function|class)\s+/g, '$1 ');
90
+ return transformed;
91
+ }
92
+ /**
93
+ * Execute an action script in an isolated sandbox.
94
+ *
95
+ * The action code should export a default async function:
96
+ * ```javascript
97
+ * export default async function myAction(input, ctx) {
98
+ * return { content: [{ type: 'text', text: 'Result' }] };
99
+ * }
100
+ * ```
101
+ */
102
+ export async function executeAction(actionCode, input, contextOptions, sandboxOptions = {}) {
103
+ const opts = { ...DEFAULT_SANDBOX_OPTIONS, ...sandboxOptions };
104
+ // Create action context
105
+ const actionContext = createActionContext(contextOptions);
106
+ // Create isolated-vm isolate
107
+ const isolate = new ivm.Isolate({
108
+ memoryLimit: opts.memoryLimit,
109
+ });
110
+ try {
111
+ // Transform ES module syntax to CommonJS-style
112
+ const transformedCode = transformActionCode(actionCode);
113
+ // Create context
114
+ const context = await isolate.createContext();
115
+ const global = context.global;
116
+ // Create a deferred result holder
117
+ let resolveResult;
118
+ let rejectResult;
119
+ const resultPromise = new Promise((resolve, reject) => {
120
+ resolveResult = resolve;
121
+ rejectResult = reject;
122
+ });
123
+ // Create log callback
124
+ const logCallback = (level, message) => {
125
+ actionContext.log(level, message);
126
+ };
127
+ // Create fetch wrapper that returns a JSON string (not an object).
128
+ // isolated-vm cannot transfer objects or Promises across the boundary
129
+ // via Reference.apply(), but strings transfer cleanly.
130
+ const fetchCallback = async (url, optionsJson) => {
131
+ try {
132
+ const options = optionsJson ? JSON.parse(optionsJson) : {};
133
+ const response = await actionContext.fetch(url, options);
134
+ const text = await response.text();
135
+ return JSON.stringify({
136
+ ok: response.ok,
137
+ status: response.status,
138
+ statusText: response.statusText,
139
+ text: text,
140
+ headers: Object.fromEntries(response.headers.entries()),
141
+ });
142
+ }
143
+ catch (error) {
144
+ return JSON.stringify({
145
+ ok: false,
146
+ status: 0,
147
+ statusText: 'Error',
148
+ error: error instanceof Error ? error.message : String(error),
149
+ });
150
+ }
151
+ };
152
+ // Create getSecret wrapper (returns null instead of undefined for isolated-vm boundary)
153
+ const getSecretCallback = (name, url) => {
154
+ return actionContext.getSecret(name, url) ?? null;
155
+ };
156
+ // Set up callbacks in the isolate
157
+ // _fetch uses ivm.Reference (not Callback) because it is async.
158
+ // ivm.Callback cannot return Promises across the isolate boundary.
159
+ await global.set('_log', new ivm.Callback(logCallback));
160
+ await global.set('_fetch', new ivm.Reference(fetchCallback));
161
+ await global.set('_resolve', new ivm.Callback((result) => resolveResult(result)));
162
+ await global.set('_reject', new ivm.Callback((error) => rejectResult(new Error(error))));
163
+ await global.set('_input', new ivm.ExternalCopy(input).copyInto());
164
+ await global.set('_getSecret', new ivm.Callback(getSecretCallback));
165
+ await global.set('_manifest', new ivm.ExternalCopy(actionContext.manifest).copyInto());
166
+ // Create the wrapper script with full capture-then-delete pattern (AC17, AC18)
167
+ const wrapperScript = `
168
+ // Capture ALL globals into local const variables BEFORE anything else
169
+ const __fetch__ = _fetch;
170
+ const __log__ = _log;
171
+ const __manifest__ = _manifest;
172
+ const __getSecret__ = _getSecret;
173
+ const __input__ = _input;
174
+ const __resolve__ = _resolve;
175
+ const __reject__ = _reject;
176
+
177
+ // Delete all raw globals immediately
178
+ delete globalThis._fetch;
179
+ delete globalThis._log;
180
+ delete globalThis._resolve;
181
+ delete globalThis._reject;
182
+ delete globalThis._input;
183
+ delete globalThis._manifest;
184
+ delete globalThis._getSecret;
185
+
186
+ // Build ctx from captured locals only
187
+ const ctx = {
188
+ manifest: __manifest__,
189
+ fetch: async (url, options) => {
190
+ // __fetch__ is an ivm.Reference to an async host function.
191
+ // It returns a JSON string; we parse it and add the json() helper.
192
+ const optionsJson = options ? JSON.stringify(options) : undefined;
193
+ const raw = await __fetch__.apply(undefined, [url, optionsJson], { result: { promise: true, copy: true } });
194
+ const res = JSON.parse(raw);
195
+ res.json = function() { return JSON.parse(res.text); };
196
+ return res;
197
+ },
198
+ log: (level, message) => {
199
+ __log__(level, message);
200
+ },
201
+ getSecret: (name, url) => {
202
+ const result = __getSecret__(name, url);
203
+ return result === null ? undefined : result;
204
+ },
205
+ };
206
+
207
+ // Transformed action code
208
+ ${transformedCode}
209
+
210
+ // Find the action function
211
+ const actionFn = typeof __default__ !== 'undefined' ? __default__ : null;
212
+
213
+ if (typeof actionFn !== 'function') {
214
+ __reject__('Action must export a default async function');
215
+ } else {
216
+ // Execute the action using captured locals
217
+ Promise.resolve()
218
+ .then(() => actionFn(__input__, ctx))
219
+ .then(result => {
220
+ if (!result || !Array.isArray(result.content)) {
221
+ __reject__('Action must return { content: [...] }');
222
+ } else {
223
+ __resolve__(result);
224
+ }
225
+ })
226
+ .catch(err => {
227
+ __reject__(err.message || String(err));
228
+ });
229
+ }
230
+ `;
231
+ // Compile and run the script
232
+ const script = await isolate.compileScript(wrapperScript);
233
+ // Run with timeout
234
+ await script.run(context, {
235
+ timeout: opts.cpuTimeLimit,
236
+ });
237
+ // Wait for the result with wall timeout
238
+ const rawResult = await Promise.race([
239
+ resultPromise,
240
+ new Promise((_, reject) => {
241
+ setTimeout(() => reject(new Error('Action timeout')), opts.wallTimeLimit);
242
+ }),
243
+ ]);
244
+ // Validate and truncate result if too large
245
+ return validateResultSize(rawResult);
246
+ }
247
+ catch (error) {
248
+ const message = error instanceof Error ? error.message : String(error);
249
+ return {
250
+ content: [{ type: 'text', text: `Execution error: ${message}` }],
251
+ isError: true,
252
+ };
253
+ }
254
+ finally {
255
+ // Clean up
256
+ isolate.dispose();
257
+ }
258
+ }
259
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/sandbox/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Sandbox module - executor, context, and URL validation.
3
+ * @module sandbox
4
+ */
5
+ export * from './executor.js';
6
+ export * from './context.js';
7
+ export * from './url-validator.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Sandbox module - executor, context, and URL validation.
3
+ * @module sandbox
4
+ */
5
+ export * from './executor.js';
6
+ export * from './context.js';
7
+ export * from './url-validator.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * URL validation for SSRF protection and redirect handling.
3
+ * @module sandbox/url-validator
4
+ */
5
+ /**
6
+ * URL validation options.
7
+ */
8
+ export interface UrlValidationOptions {
9
+ /** Allowed URL schemes (default: ['https']) */
10
+ allowedSchemes?: string[];
11
+ /** Maximum number of redirects to follow */
12
+ maxRedirects?: number;
13
+ /** Whether to allow localhost (default: false) */
14
+ allowLocalhost?: boolean;
15
+ /** Custom blocked IP ranges */
16
+ blockedIpRanges?: string[];
17
+ }
18
+ /**
19
+ * Check if IP is in CIDR range (supports IPv4 and IPv6).
20
+ */
21
+ export declare function isIpInCidr(ip: string, cidr: string): boolean;
22
+ /**
23
+ * Validate URL for SSRF protection.
24
+ * @throws Error if URL is invalid or blocked
25
+ */
26
+ export declare function validateUrl(urlString: string, options?: UrlValidationOptions): Promise<URL>;
27
+ /**
28
+ * Validate a redirect URL.
29
+ * Re-validates all SSRF protections for the redirect target.
30
+ */
31
+ export declare function validateRedirect(redirectUrl: string, _originalUrl: string, options?: UrlValidationOptions): Promise<URL>;
32
+ /**
33
+ * Check if a URL is HTTPS.
34
+ */
35
+ export declare function isHttps(url: string): boolean;
36
+ /**
37
+ * Extract hostname from URL.
38
+ */
39
+ export declare function getHostname(url: string): string | undefined;
40
+ //# sourceMappingURL=url-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-validator.d.ts","sourceRoot":"","sources":["../../src/sandbox/url-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+BAA+B;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAiDD;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAsC5D;AA8BD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,GAAG,CAAC,CAyCd;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,GAAG,CAAC,CAOd;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAM5C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM3D"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * URL validation for SSRF protection and redirect handling.
3
+ * @module sandbox/url-validator
4
+ */
5
+ import * as dns from 'node:dns/promises';
6
+ /**
7
+ * Default validation options.
8
+ */
9
+ const DEFAULT_OPTIONS = {
10
+ allowedSchemes: ['https'],
11
+ maxRedirects: 5,
12
+ allowLocalhost: false,
13
+ blockedIpRanges: [],
14
+ };
15
+ /**
16
+ * Blocked IP ranges for SSRF protection.
17
+ */
18
+ const BLOCKED_PRIVATE_RANGES = [
19
+ '10.0.0.0/8',
20
+ '172.16.0.0/12',
21
+ '192.168.0.0/16',
22
+ '127.0.0.0/8',
23
+ '169.254.0.0/16',
24
+ '::1/128',
25
+ 'fc00::/7',
26
+ 'fe80::/10',
27
+ ];
28
+ /**
29
+ * Parse an IPv6 address into a BigInt (128-bit).
30
+ */
31
+ function parseIpv6ToBigInt(ip) {
32
+ const halves = ip.split('::');
33
+ const left = halves[0] ? halves[0].split(':').filter(s => s !== '') : [];
34
+ const right = halves.length > 1 && halves[1] ? halves[1].split(':').filter(s => s !== '') : [];
35
+ const groups = [];
36
+ for (const g of left)
37
+ groups.push(parseInt(g, 16));
38
+ const fill = 8 - left.length - right.length;
39
+ for (let i = 0; i < fill; i++)
40
+ groups.push(0);
41
+ for (const g of right)
42
+ groups.push(parseInt(g, 16));
43
+ let result = BigInt(0);
44
+ for (const group of groups) {
45
+ result = (result << BigInt(16)) | BigInt(group);
46
+ }
47
+ return result;
48
+ }
49
+ /**
50
+ * Check if IP is in CIDR range (supports IPv4 and IPv6).
51
+ */
52
+ export function isIpInCidr(ip, cidr) {
53
+ const [range, bitsStr] = cidr.split('/');
54
+ if (!range) {
55
+ return false;
56
+ }
57
+ const isIpv6 = ip.includes(':');
58
+ const isRangeIpv6 = range.includes(':');
59
+ // Must be same address family
60
+ if (isIpv6 !== isRangeIpv6)
61
+ return false;
62
+ if (isIpv6) {
63
+ const bits = bitsStr !== undefined ? parseInt(bitsStr, 10) : 128;
64
+ const ipNum = parseIpv6ToBigInt(ip);
65
+ const rangeNum = parseIpv6ToBigInt(range);
66
+ const mask = bits === 0 ? BigInt(0) : ((BigInt(1) << BigInt(128)) - BigInt(1)) << BigInt(128 - bits);
67
+ return (ipNum & mask) === (rangeNum & mask);
68
+ }
69
+ // IPv4
70
+ const rangeParts = range.split('.').map(Number);
71
+ const ipParts = ip.split('.').map(Number);
72
+ if (rangeParts.length !== 4 || ipParts.length !== 4) {
73
+ return false;
74
+ }
75
+ const bits = bitsStr !== undefined ? parseInt(bitsStr, 10) : 32;
76
+ let maskNum = 0;
77
+ for (let i = 0; i < bits; i++) {
78
+ maskNum |= (1 << (31 - i));
79
+ }
80
+ const rangeNum = ((rangeParts[0] ?? 0) << 24) | ((rangeParts[1] ?? 0) << 16) | ((rangeParts[2] ?? 0) << 8) | (rangeParts[3] ?? 0);
81
+ const ipNum = ((ipParts[0] ?? 0) << 24) | ((ipParts[1] ?? 0) << 16) | ((ipParts[2] ?? 0) << 8) | (ipParts[3] ?? 0);
82
+ return (rangeNum & maskNum) === (ipNum & maskNum);
83
+ }
84
+ /**
85
+ * Check if IP is in any blocked range.
86
+ */
87
+ function isBlockedIp(ip, options) {
88
+ // Check custom blocked ranges
89
+ for (const range of options.blockedIpRanges) {
90
+ if (isIpInCidr(ip, range)) {
91
+ return true;
92
+ }
93
+ }
94
+ // Check default private ranges
95
+ for (const range of BLOCKED_PRIVATE_RANGES) {
96
+ if (isIpInCidr(ip, range)) {
97
+ return true;
98
+ }
99
+ }
100
+ // Check localhost
101
+ if (!options.allowLocalhost) {
102
+ if (ip === '127.0.0.1' || ip === '::1' || ip === 'localhost') {
103
+ return true;
104
+ }
105
+ }
106
+ return false;
107
+ }
108
+ /**
109
+ * Validate URL for SSRF protection.
110
+ * @throws Error if URL is invalid or blocked
111
+ */
112
+ export async function validateUrl(urlString, options = {}) {
113
+ const opts = { ...DEFAULT_OPTIONS, ...options };
114
+ // Parse URL
115
+ let url;
116
+ try {
117
+ url = new URL(urlString);
118
+ }
119
+ catch {
120
+ throw new Error(`Invalid URL: ${urlString}`);
121
+ }
122
+ // Check scheme
123
+ if (!opts.allowedSchemes.includes(url.protocol.replace(':', ''))) {
124
+ throw new Error(`URL scheme "${url.protocol}" not allowed. Allowed: ${opts.allowedSchemes.join(', ')}. Use --allow-http to allow insecure HTTP connections.`);
125
+ }
126
+ // Resolve hostname to IP for SSRF protection
127
+ const hostname = url.hostname;
128
+ let ips;
129
+ try {
130
+ // Try to resolve as IPv4 first, then IPv6
131
+ const result = await dns.lookup(hostname, { all: true });
132
+ ips = result.map((r) => r.address);
133
+ }
134
+ catch {
135
+ throw new Error(`Failed to resolve hostname: ${hostname}`);
136
+ }
137
+ // Check all resolved IPs
138
+ for (const ip of ips) {
139
+ if (isBlockedIp(ip, opts)) {
140
+ throw new Error(`Blocked IP address: ${ip} (resolved from ${hostname}). ` +
141
+ `This appears to be a private/internal network address.`);
142
+ }
143
+ }
144
+ return url;
145
+ }
146
+ /**
147
+ * Validate a redirect URL.
148
+ * Re-validates all SSRF protections for the redirect target.
149
+ */
150
+ export async function validateRedirect(redirectUrl, _originalUrl, options = {}) {
151
+ // Validate the redirect URL with all SSRF checks
152
+ const url = await validateUrl(redirectUrl, options);
153
+ // Log redirect for audit (caller provides audit logger at a higher level)
154
+ return url;
155
+ }
156
+ /**
157
+ * Check if a URL is HTTPS.
158
+ */
159
+ export function isHttps(url) {
160
+ try {
161
+ return new URL(url).protocol === 'https:';
162
+ }
163
+ catch {
164
+ return false;
165
+ }
166
+ }
167
+ /**
168
+ * Extract hostname from URL.
169
+ */
170
+ export function getHostname(url) {
171
+ try {
172
+ return new URL(url).hostname;
173
+ }
174
+ catch {
175
+ return undefined;
176
+ }
177
+ }
178
+ //# sourceMappingURL=url-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-validator.js","sourceRoot":"","sources":["../../src/sandbox/url-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Secrets module - manager and pattern matching.
3
+ * @module secrets
4
+ */
5
+ export * from './manager.js';
6
+ export * from './patterns.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Secrets module - manager and pattern matching.
3
+ * @module secrets
4
+ */
5
+ export * from './manager.js';
6
+ export * from './patterns.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/secrets/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Secret approval and scoping manager.
3
+ * @module secrets/manager
4
+ */
5
+ import { Secret } from '../manifest/schema.js';
6
+ /**
7
+ * Approved secret with its scope patterns.
8
+ */
9
+ export interface ApprovedSecret {
10
+ name: string;
11
+ value: string;
12
+ scopes: string[];
13
+ }
14
+ /**
15
+ * Secrets manager handles secret approval and scoped access.
16
+ */
17
+ export declare class SecretsManager {
18
+ private approvedSecrets;
19
+ /**
20
+ * Approve a secret with its value and scope patterns.
21
+ */
22
+ approve(secret: Secret, value: string): void;
23
+ /**
24
+ * Check if a secret is approved.
25
+ */
26
+ isApproved(name: string): boolean;
27
+ /**
28
+ * Get a secret value if approved and URL is in scope.
29
+ * @returns The secret value, or undefined if not approved or out of scope
30
+ */
31
+ getSecret(name: string, url?: string): string | undefined;
32
+ /**
33
+ * Get all approved secrets for a specific URL.
34
+ * Only returns secrets whose scopes include the URL.
35
+ */
36
+ getSecretsForUrl(url: string): Record<string, string>;
37
+ /**
38
+ * Get all approved secrets (without scope validation).
39
+ * Use with caution - for passing to worker process only.
40
+ */
41
+ getAllSecrets(): Record<string, string>;
42
+ /**
43
+ * Get scope patterns for a secret.
44
+ */
45
+ getScopes(name: string): string[] | undefined;
46
+ /**
47
+ * Clear all approved secrets.
48
+ */
49
+ clear(): void;
50
+ /**
51
+ * List all approved secret names.
52
+ */
53
+ listApproved(): string[];
54
+ }
55
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/secrets/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAA0C;IAEjE;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ5C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAkBzD;;;OAGG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAerD;;;OAGG;IACH,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAQvC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAI7C;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,YAAY,IAAI,MAAM,EAAE;CAGzB"}