@easynet/agent-tool 1.0.61 → 1.0.63

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 (70) hide show
  1. package/dist/api/adapters/LangChainToolsHub.d.ts.map +1 -1
  2. package/dist/api/expose/extension-init/initExtension.d.ts.map +1 -1
  3. package/dist/api/main.cjs +29 -13
  4. package/dist/api/main.d.ts +34 -0
  5. package/dist/api/main.d.ts.map +1 -1
  6. package/dist/api/main.js +2 -2
  7. package/dist/api/runtimeFromConfig.d.ts +2 -5
  8. package/dist/api/runtimeFromConfig.d.ts.map +1 -1
  9. package/dist/api/runtimeFromConfig.helpers.d.ts +12 -0
  10. package/dist/api/runtimeFromConfig.helpers.d.ts.map +1 -0
  11. package/dist/build.cjs +1 -0
  12. package/dist/build.js +1 -0
  13. package/dist/chunk-DEDDPMBU.js +3 -0
  14. package/dist/chunk-DEDDPMBU.js.map +1 -0
  15. package/dist/chunk-FWWN4D2F.js +3 -0
  16. package/dist/chunk-FWWN4D2F.js.map +1 -0
  17. package/dist/chunk-ICHSEIZN.cjs +4 -0
  18. package/dist/chunk-ICHSEIZN.cjs.map +1 -0
  19. package/dist/{chunk-HK4GTFTQ.cjs → chunk-M2GEHWPN.cjs} +41 -40
  20. package/dist/chunk-M2GEHWPN.cjs.map +1 -0
  21. package/dist/chunk-NKYFYALQ.js +181 -0
  22. package/dist/chunk-NKYFYALQ.js.map +1 -0
  23. package/dist/chunk-NOGGIM7B.cjs +4 -0
  24. package/dist/chunk-NOGGIM7B.cjs.map +1 -0
  25. package/dist/chunk-R55NXJIH.cjs +184 -0
  26. package/dist/chunk-R55NXJIH.cjs.map +1 -0
  27. package/dist/{chunk-NVT4X4CB.js → chunk-RJAF5XY6.js} +40 -39
  28. package/dist/chunk-RJAF5XY6.js.map +1 -0
  29. package/dist/{chunk-ZH5MH3AK.cjs → chunk-U67QDQFQ.cjs} +73 -41
  30. package/dist/chunk-U67QDQFQ.cjs.map +1 -0
  31. package/dist/chunk-WO4LZKPQ.cjs +359 -0
  32. package/dist/chunk-WO4LZKPQ.cjs.map +1 -0
  33. package/dist/chunk-YL6RC7HQ.cjs +4 -0
  34. package/dist/chunk-YL6RC7HQ.cjs.map +1 -0
  35. package/dist/chunk-YLWTSNTT.js +3 -0
  36. package/dist/chunk-YLWTSNTT.js.map +1 -0
  37. package/dist/{chunk-QPKBEU64.js → chunk-YMHUDRYE.js} +59 -31
  38. package/dist/chunk-YMHUDRYE.js.map +1 -0
  39. package/dist/chunk-YPGF5Y2Y.js +341 -0
  40. package/dist/chunk-YPGF5Y2Y.js.map +1 -0
  41. package/dist/core/index.cjs +1 -0
  42. package/dist/core/index.js +1 -0
  43. package/dist/core/runtime.cjs +1 -0
  44. package/dist/core/runtime.js +1 -0
  45. package/dist/extension.cjs +54 -355
  46. package/dist/extension.cjs.map +1 -1
  47. package/dist/extension.js +3 -339
  48. package/dist/extension.js.map +1 -1
  49. package/dist/index.cjs +96 -17
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.ts +50 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +59 -7
  54. package/dist/index.js.map +1 -1
  55. package/dist/security.cjs +11 -178
  56. package/dist/security.cjs.map +1 -1
  57. package/dist/security.js +2 -179
  58. package/dist/security.js.map +1 -1
  59. package/dist/utils/cli/help.d.ts +2 -0
  60. package/dist/utils/cli/help.d.ts.map +1 -0
  61. package/dist/utils/cli/index.cjs +95 -73
  62. package/dist/utils/cli/index.cjs.map +1 -1
  63. package/dist/utils/cli/index.d.ts.map +1 -1
  64. package/dist/utils/cli/index.js +84 -62
  65. package/dist/utils/cli/index.js.map +1 -1
  66. package/package.json +3 -3
  67. package/dist/chunk-HK4GTFTQ.cjs.map +0 -1
  68. package/dist/chunk-NVT4X4CB.js.map +0 -1
  69. package/dist/chunk-QPKBEU64.js.map +0 -1
  70. package/dist/chunk-ZH5MH3AK.cjs.map +0 -1
@@ -0,0 +1,181 @@
1
+ import { createTaggedError } from './chunk-RZTTO5MQ.js';
2
+ import { lookup } from 'dns/promises';
3
+
4
+ async function validateUrl(url, options) {
5
+ let parsed;
6
+ try {
7
+ parsed = new URL(url);
8
+ } catch {
9
+ throw createTaggedError(
10
+ "HTTP_DISALLOWED_HOST",
11
+ `Invalid URL: ${url}`,
12
+ { url }
13
+ );
14
+ }
15
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
16
+ throw createTaggedError(
17
+ "HTTP_DISALLOWED_HOST",
18
+ `Protocol not allowed: ${parsed.protocol}. Only http: and https: are supported.`,
19
+ { url, protocol: parsed.protocol }
20
+ );
21
+ }
22
+ const hostname = parsed.hostname;
23
+ if (!isHostAllowed(hostname, options.allowedHosts)) {
24
+ throw createTaggedError(
25
+ "HTTP_DISALLOWED_HOST",
26
+ `Host "${hostname}" is not in the allowed hosts list`,
27
+ { url, hostname, allowedHosts: options.allowedHosts }
28
+ );
29
+ }
30
+ if (isHostBlocked(hostname, options.blockedHosts)) {
31
+ throw createTaggedError(
32
+ "HTTP_DISALLOWED_HOST",
33
+ `Host "${hostname}" is in the blocked hosts list`,
34
+ { url, hostname, blockedHosts: options.blockedHosts }
35
+ );
36
+ }
37
+ try {
38
+ const { address } = await lookup(hostname);
39
+ if (isIpInBlockedCidrs(address, options.blockedCidrs)) {
40
+ throw createTaggedError(
41
+ "HTTP_DISALLOWED_HOST",
42
+ `Host "${hostname}" resolves to blocked IP: ${address}`,
43
+ { url, hostname, resolvedIp: address }
44
+ );
45
+ }
46
+ } catch (err) {
47
+ if (err instanceof Error && err.kind === "HTTP_DISALLOWED_HOST") {
48
+ throw err;
49
+ }
50
+ throw createTaggedError(
51
+ "HTTP_DISALLOWED_HOST",
52
+ `DNS resolution failed for host "${hostname}": ${err instanceof Error ? err.message : String(err)}`,
53
+ { url, hostname }
54
+ );
55
+ }
56
+ return parsed;
57
+ }
58
+ function isHostAllowed(hostname, allowedHosts) {
59
+ for (const pattern of allowedHosts) {
60
+ if (pattern === "*") {
61
+ return true;
62
+ }
63
+ if (pattern.startsWith("*.")) {
64
+ const suffix = pattern.slice(1);
65
+ if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {
66
+ return true;
67
+ }
68
+ } else if (hostname === pattern) {
69
+ return true;
70
+ }
71
+ }
72
+ return false;
73
+ }
74
+ function isHostBlocked(hostname, blockedHosts) {
75
+ for (const pattern of blockedHosts) {
76
+ if (pattern === "*") {
77
+ return true;
78
+ }
79
+ if (pattern.startsWith("*.")) {
80
+ const suffix = pattern.slice(1);
81
+ if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {
82
+ return true;
83
+ }
84
+ } else if (hostname === pattern) {
85
+ return true;
86
+ }
87
+ }
88
+ return false;
89
+ }
90
+ function isIpInBlockedCidrs(ip, cidrs) {
91
+ const normalizedIp = normalizeIp(ip);
92
+ if (!normalizedIp) return false;
93
+ for (const cidr of cidrs) {
94
+ if (cidr.includes(":")) {
95
+ if (!ip.includes(":")) continue;
96
+ if (isIpv6InCidr(ip, cidr)) return true;
97
+ } else {
98
+ if (isIpv4InCidr(normalizedIp, cidr)) return true;
99
+ }
100
+ }
101
+ return false;
102
+ }
103
+ function normalizeIp(ip) {
104
+ if (ip.startsWith("::ffff:")) {
105
+ return ip.slice(7);
106
+ }
107
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(ip)) {
108
+ return ip;
109
+ }
110
+ return null;
111
+ }
112
+ function isIpv4InCidr(ip, cidr) {
113
+ const [cidrIp, prefixStr] = cidr.split("/");
114
+ if (!cidrIp || !prefixStr) return false;
115
+ const prefix = parseInt(prefixStr, 10);
116
+ if (isNaN(prefix) || prefix < 0 || prefix > 32) return false;
117
+ const ipNum = ipv4ToNum(ip);
118
+ const cidrNum = ipv4ToNum(cidrIp);
119
+ if (ipNum === null || cidrNum === null) return false;
120
+ const mask = prefix === 0 ? 0 : -1 << 32 - prefix >>> 0;
121
+ return (ipNum & mask) === (cidrNum & mask);
122
+ }
123
+ function ipv4ToNum(ip) {
124
+ const parts = ip.split(".");
125
+ if (parts.length !== 4) return null;
126
+ let num = 0;
127
+ for (const part of parts) {
128
+ const n = parseInt(part, 10);
129
+ if (isNaN(n) || n < 0 || n > 255) return null;
130
+ num = num << 8 | n;
131
+ }
132
+ return num >>> 0;
133
+ }
134
+ function isIpv6InCidr(ip, cidr) {
135
+ const [cidrIp, prefixStr] = cidr.split("/");
136
+ if (!cidrIp || !prefixStr) return false;
137
+ const prefix = parseInt(prefixStr, 10);
138
+ if (isNaN(prefix)) return false;
139
+ const ipBytes = expandIpv6(ip);
140
+ const cidrBytes = expandIpv6(cidrIp);
141
+ if (!ipBytes || !cidrBytes) return false;
142
+ const fullBytes = Math.floor(prefix / 8);
143
+ for (let i = 0; i < fullBytes && i < 16; i++) {
144
+ if (ipBytes[i] !== cidrBytes[i]) return false;
145
+ }
146
+ const remainingBits = prefix % 8;
147
+ if (remainingBits > 0 && fullBytes < 16) {
148
+ const mask = -1 << 8 - remainingBits & 255;
149
+ if ((ipBytes[fullBytes] & mask) !== (cidrBytes[fullBytes] & mask)) return false;
150
+ }
151
+ return true;
152
+ }
153
+ function expandIpv6(ip) {
154
+ const zoneIdx = ip.indexOf("%");
155
+ if (zoneIdx !== -1) ip = ip.slice(0, zoneIdx);
156
+ const parts = ip.split("::");
157
+ if (parts.length > 2) return null;
158
+ const bytes = new Array(16).fill(0);
159
+ const expandGroup = (group) => {
160
+ if (!group) return [];
161
+ return group.split(":").flatMap((hex) => {
162
+ const val = parseInt(hex || "0", 16);
163
+ return [val >> 8 & 255, val & 255];
164
+ });
165
+ };
166
+ if (parts.length === 1) {
167
+ const expanded = expandGroup(parts[0]);
168
+ if (expanded.length !== 16) return null;
169
+ return expanded;
170
+ }
171
+ const left = expandGroup(parts[0]);
172
+ const right = expandGroup(parts[1]);
173
+ if (left.length + right.length > 16) return null;
174
+ for (let i = 0; i < left.length; i++) bytes[i] = left[i];
175
+ for (let i = 0; i < right.length; i++) bytes[16 - right.length + i] = right[i];
176
+ return bytes;
177
+ }
178
+
179
+ export { isIpInBlockedCidrs, validateUrl };
180
+ //# sourceMappingURL=chunk-NKYFYALQ.js.map
181
+ //# sourceMappingURL=chunk-NKYFYALQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/security/ssrf.ts"],"names":[],"mappings":"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","file":"chunk-NKYFYALQ.js","sourcesContent":["import { lookup } from \"node:dns/promises\";\nimport { createTaggedError } from \"../core/runtime/Retry.js\";\n\n/**\n * Options for validateUrl. Unified rule: allow iff host is in allowedHosts AND not in blockedHosts.\n * - \"Default allow all + blocklist\": allowedHosts: [\"*\"], blockedHosts: [\"*.internal\", ...]\n * - \"Default disallow all + allowlist\": allowedHosts: [\"api.github.com\", ...], blockedHosts: []\n */\nexport interface ValidateUrlOptions {\n /** Allow only these hosts. Use [\"*\"] for allow-all. Supports \"*.example.com\", exact host. */\n allowedHosts: string[];\n /** Block these hosts even if allowed. Supports \"*.internal\", exact host. Merged with allowlist. */\n blockedHosts: string[];\n /** CIDR ranges to block (resolved IP). */\n blockedCidrs: string[];\n}\n\n/**\n * Validate a URL: allow iff (host in allowedHosts) AND (host not in blockedHosts). Then check blockedCidrs on resolved IP.\n *\n * @throws HTTP_DISALLOWED_HOST if the URL is blocked\n */\nexport async function validateUrl(url: string, options: ValidateUrlOptions): Promise<URL> {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Invalid URL: ${url}`,\n { url },\n );\n }\n\n // Only allow http/https\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Protocol not allowed: ${parsed.protocol}. Only http: and https: are supported.`,\n { url, protocol: parsed.protocol },\n );\n }\n\n const hostname = parsed.hostname;\n\n if (!isHostAllowed(hostname, options.allowedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is not in the allowed hosts list`,\n { url, hostname, allowedHosts: options.allowedHosts },\n );\n }\n if (isHostBlocked(hostname, options.blockedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is in the blocked hosts list`,\n { url, hostname, blockedHosts: options.blockedHosts },\n );\n }\n\n // DNS resolve and check against blocked CIDRs\n try {\n const { address } = await lookup(hostname);\n if (isIpInBlockedCidrs(address, options.blockedCidrs)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" resolves to blocked IP: ${address}`,\n { url, hostname, resolvedIp: address },\n );\n }\n } catch (err) {\n // Re-throw our tagged errors\n if (err instanceof Error && (err as any).kind === \"HTTP_DISALLOWED_HOST\") {\n throw err;\n }\n // DNS resolution failure — block by default\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `DNS resolution failed for host \"${hostname}\": ${err instanceof Error ? err.message : String(err)}`,\n { url, hostname },\n );\n }\n\n return parsed;\n}\n\n/**\n * Check if a hostname matches any entry in the allowed hosts list.\n * Supports: exact \"*\" (allow any host), wildcard prefix (e.g. \"*.github.com\"), or exact host.\n */\nfunction isHostAllowed(hostname: string, allowedHosts: string[]): boolean {\n for (const pattern of allowedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1); // \".github.com\"\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a hostname matches any entry in the blocked hosts list (same pattern rules as allowlist).\n */\nfunction isHostBlocked(hostname: string, blockedHosts: string[]): boolean {\n for (const pattern of blockedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1);\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if an IPv4 address falls within any blocked CIDR range.\n */\nexport function isIpInBlockedCidrs(ip: string, cidrs: string[]): boolean {\n // Handle IPv4-mapped IPv6\n const normalizedIp = normalizeIp(ip);\n if (!normalizedIp) return false;\n\n for (const cidr of cidrs) {\n if (cidr.includes(\":\")) {\n // IPv6 CIDR — skip for IPv4 addresses\n if (!ip.includes(\":\")) continue;\n if (isIpv6InCidr(ip, cidr)) return true;\n } else {\n if (isIpv4InCidr(normalizedIp, cidr)) return true;\n }\n }\n return false;\n}\n\nfunction normalizeIp(ip: string): string | null {\n // Handle IPv4-mapped IPv6 (e.g. \"::ffff:127.0.0.1\")\n if (ip.startsWith(\"::ffff:\")) {\n return ip.slice(7);\n }\n // Pure IPv4\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(ip)) {\n return ip;\n }\n return null;\n}\n\nfunction isIpv4InCidr(ip: string, cidr: string): boolean {\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix) || prefix < 0 || prefix > 32) return false;\n\n const ipNum = ipv4ToNum(ip);\n const cidrNum = ipv4ToNum(cidrIp);\n if (ipNum === null || cidrNum === null) return false;\n\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n return (ipNum & mask) === (cidrNum & mask);\n}\n\nfunction ipv4ToNum(ip: string): number | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let num = 0;\n for (const part of parts) {\n const n = parseInt(part, 10);\n if (isNaN(n) || n < 0 || n > 255) return null;\n num = (num << 8) | n;\n }\n return num >>> 0;\n}\n\nfunction isIpv6InCidr(ip: string, cidr: string): boolean {\n // Simplified IPv6 CIDR matching for common cases (::1, fc00::, fe80::)\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix)) return false;\n\n const ipBytes = expandIpv6(ip);\n const cidrBytes = expandIpv6(cidrIp);\n if (!ipBytes || !cidrBytes) return false;\n\n // Compare prefix bits\n const fullBytes = Math.floor(prefix / 8);\n for (let i = 0; i < fullBytes && i < 16; i++) {\n if (ipBytes[i] !== cidrBytes[i]) return false;\n }\n\n const remainingBits = prefix % 8;\n if (remainingBits > 0 && fullBytes < 16) {\n const mask = (~0 << (8 - remainingBits)) & 0xff;\n if ((ipBytes[fullBytes]! & mask) !== (cidrBytes[fullBytes]! & mask)) return false;\n }\n\n return true;\n}\n\nfunction expandIpv6(ip: string): number[] | null {\n // Remove zone ID\n const zoneIdx = ip.indexOf(\"%\");\n if (zoneIdx !== -1) ip = ip.slice(0, zoneIdx);\n\n const parts = ip.split(\"::\");\n if (parts.length > 2) return null;\n\n const bytes: number[] = new Array(16).fill(0);\n\n const expandGroup = (group: string): number[] => {\n if (!group) return [];\n return group.split(\":\").flatMap((hex) => {\n const val = parseInt(hex || \"0\", 16);\n return [(val >> 8) & 0xff, val & 0xff];\n });\n };\n\n if (parts.length === 1) {\n const expanded = expandGroup(parts[0]!);\n if (expanded.length !== 16) return null;\n return expanded;\n }\n\n const left = expandGroup(parts[0]!);\n const right = expandGroup(parts[1]!);\n\n if (left.length + right.length > 16) return null;\n\n for (let i = 0; i < left.length; i++) bytes[i] = left[i]!;\n for (let i = 0; i < right.length; i++) bytes[16 - right.length + i] = right[i]!;\n\n return bytes;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ 'use strict';
2
+
3
+ //# sourceMappingURL=chunk-NOGGIM7B.cjs.map
4
+ //# sourceMappingURL=chunk-NOGGIM7B.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-NOGGIM7B.cjs"}
@@ -0,0 +1,184 @@
1
+ 'use strict';
2
+
3
+ var chunkXPGHS4W7_cjs = require('./chunk-XPGHS4W7.cjs');
4
+ var promises = require('dns/promises');
5
+
6
+ async function validateUrl(url, options) {
7
+ let parsed;
8
+ try {
9
+ parsed = new URL(url);
10
+ } catch {
11
+ throw chunkXPGHS4W7_cjs.createTaggedError(
12
+ "HTTP_DISALLOWED_HOST",
13
+ `Invalid URL: ${url}`,
14
+ { url }
15
+ );
16
+ }
17
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
18
+ throw chunkXPGHS4W7_cjs.createTaggedError(
19
+ "HTTP_DISALLOWED_HOST",
20
+ `Protocol not allowed: ${parsed.protocol}. Only http: and https: are supported.`,
21
+ { url, protocol: parsed.protocol }
22
+ );
23
+ }
24
+ const hostname = parsed.hostname;
25
+ if (!isHostAllowed(hostname, options.allowedHosts)) {
26
+ throw chunkXPGHS4W7_cjs.createTaggedError(
27
+ "HTTP_DISALLOWED_HOST",
28
+ `Host "${hostname}" is not in the allowed hosts list`,
29
+ { url, hostname, allowedHosts: options.allowedHosts }
30
+ );
31
+ }
32
+ if (isHostBlocked(hostname, options.blockedHosts)) {
33
+ throw chunkXPGHS4W7_cjs.createTaggedError(
34
+ "HTTP_DISALLOWED_HOST",
35
+ `Host "${hostname}" is in the blocked hosts list`,
36
+ { url, hostname, blockedHosts: options.blockedHosts }
37
+ );
38
+ }
39
+ try {
40
+ const { address } = await promises.lookup(hostname);
41
+ if (isIpInBlockedCidrs(address, options.blockedCidrs)) {
42
+ throw chunkXPGHS4W7_cjs.createTaggedError(
43
+ "HTTP_DISALLOWED_HOST",
44
+ `Host "${hostname}" resolves to blocked IP: ${address}`,
45
+ { url, hostname, resolvedIp: address }
46
+ );
47
+ }
48
+ } catch (err) {
49
+ if (err instanceof Error && err.kind === "HTTP_DISALLOWED_HOST") {
50
+ throw err;
51
+ }
52
+ throw chunkXPGHS4W7_cjs.createTaggedError(
53
+ "HTTP_DISALLOWED_HOST",
54
+ `DNS resolution failed for host "${hostname}": ${err instanceof Error ? err.message : String(err)}`,
55
+ { url, hostname }
56
+ );
57
+ }
58
+ return parsed;
59
+ }
60
+ function isHostAllowed(hostname, allowedHosts) {
61
+ for (const pattern of allowedHosts) {
62
+ if (pattern === "*") {
63
+ return true;
64
+ }
65
+ if (pattern.startsWith("*.")) {
66
+ const suffix = pattern.slice(1);
67
+ if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {
68
+ return true;
69
+ }
70
+ } else if (hostname === pattern) {
71
+ return true;
72
+ }
73
+ }
74
+ return false;
75
+ }
76
+ function isHostBlocked(hostname, blockedHosts) {
77
+ for (const pattern of blockedHosts) {
78
+ if (pattern === "*") {
79
+ return true;
80
+ }
81
+ if (pattern.startsWith("*.")) {
82
+ const suffix = pattern.slice(1);
83
+ if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {
84
+ return true;
85
+ }
86
+ } else if (hostname === pattern) {
87
+ return true;
88
+ }
89
+ }
90
+ return false;
91
+ }
92
+ function isIpInBlockedCidrs(ip, cidrs) {
93
+ const normalizedIp = normalizeIp(ip);
94
+ if (!normalizedIp) return false;
95
+ for (const cidr of cidrs) {
96
+ if (cidr.includes(":")) {
97
+ if (!ip.includes(":")) continue;
98
+ if (isIpv6InCidr(ip, cidr)) return true;
99
+ } else {
100
+ if (isIpv4InCidr(normalizedIp, cidr)) return true;
101
+ }
102
+ }
103
+ return false;
104
+ }
105
+ function normalizeIp(ip) {
106
+ if (ip.startsWith("::ffff:")) {
107
+ return ip.slice(7);
108
+ }
109
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(ip)) {
110
+ return ip;
111
+ }
112
+ return null;
113
+ }
114
+ function isIpv4InCidr(ip, cidr) {
115
+ const [cidrIp, prefixStr] = cidr.split("/");
116
+ if (!cidrIp || !prefixStr) return false;
117
+ const prefix = parseInt(prefixStr, 10);
118
+ if (isNaN(prefix) || prefix < 0 || prefix > 32) return false;
119
+ const ipNum = ipv4ToNum(ip);
120
+ const cidrNum = ipv4ToNum(cidrIp);
121
+ if (ipNum === null || cidrNum === null) return false;
122
+ const mask = prefix === 0 ? 0 : -1 << 32 - prefix >>> 0;
123
+ return (ipNum & mask) === (cidrNum & mask);
124
+ }
125
+ function ipv4ToNum(ip) {
126
+ const parts = ip.split(".");
127
+ if (parts.length !== 4) return null;
128
+ let num = 0;
129
+ for (const part of parts) {
130
+ const n = parseInt(part, 10);
131
+ if (isNaN(n) || n < 0 || n > 255) return null;
132
+ num = num << 8 | n;
133
+ }
134
+ return num >>> 0;
135
+ }
136
+ function isIpv6InCidr(ip, cidr) {
137
+ const [cidrIp, prefixStr] = cidr.split("/");
138
+ if (!cidrIp || !prefixStr) return false;
139
+ const prefix = parseInt(prefixStr, 10);
140
+ if (isNaN(prefix)) return false;
141
+ const ipBytes = expandIpv6(ip);
142
+ const cidrBytes = expandIpv6(cidrIp);
143
+ if (!ipBytes || !cidrBytes) return false;
144
+ const fullBytes = Math.floor(prefix / 8);
145
+ for (let i = 0; i < fullBytes && i < 16; i++) {
146
+ if (ipBytes[i] !== cidrBytes[i]) return false;
147
+ }
148
+ const remainingBits = prefix % 8;
149
+ if (remainingBits > 0 && fullBytes < 16) {
150
+ const mask = -1 << 8 - remainingBits & 255;
151
+ if ((ipBytes[fullBytes] & mask) !== (cidrBytes[fullBytes] & mask)) return false;
152
+ }
153
+ return true;
154
+ }
155
+ function expandIpv6(ip) {
156
+ const zoneIdx = ip.indexOf("%");
157
+ if (zoneIdx !== -1) ip = ip.slice(0, zoneIdx);
158
+ const parts = ip.split("::");
159
+ if (parts.length > 2) return null;
160
+ const bytes = new Array(16).fill(0);
161
+ const expandGroup = (group) => {
162
+ if (!group) return [];
163
+ return group.split(":").flatMap((hex) => {
164
+ const val = parseInt(hex || "0", 16);
165
+ return [val >> 8 & 255, val & 255];
166
+ });
167
+ };
168
+ if (parts.length === 1) {
169
+ const expanded = expandGroup(parts[0]);
170
+ if (expanded.length !== 16) return null;
171
+ return expanded;
172
+ }
173
+ const left = expandGroup(parts[0]);
174
+ const right = expandGroup(parts[1]);
175
+ if (left.length + right.length > 16) return null;
176
+ for (let i = 0; i < left.length; i++) bytes[i] = left[i];
177
+ for (let i = 0; i < right.length; i++) bytes[16 - right.length + i] = right[i];
178
+ return bytes;
179
+ }
180
+
181
+ exports.isIpInBlockedCidrs = isIpInBlockedCidrs;
182
+ exports.validateUrl = validateUrl;
183
+ //# sourceMappingURL=chunk-R55NXJIH.cjs.map
184
+ //# sourceMappingURL=chunk-R55NXJIH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/security/ssrf.ts"],"names":["createTaggedError","lookup"],"mappings":"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","file":"chunk-R55NXJIH.cjs","sourcesContent":["import { lookup } from \"node:dns/promises\";\nimport { createTaggedError } from \"../core/runtime/Retry.js\";\n\n/**\n * Options for validateUrl. Unified rule: allow iff host is in allowedHosts AND not in blockedHosts.\n * - \"Default allow all + blocklist\": allowedHosts: [\"*\"], blockedHosts: [\"*.internal\", ...]\n * - \"Default disallow all + allowlist\": allowedHosts: [\"api.github.com\", ...], blockedHosts: []\n */\nexport interface ValidateUrlOptions {\n /** Allow only these hosts. Use [\"*\"] for allow-all. Supports \"*.example.com\", exact host. */\n allowedHosts: string[];\n /** Block these hosts even if allowed. Supports \"*.internal\", exact host. Merged with allowlist. */\n blockedHosts: string[];\n /** CIDR ranges to block (resolved IP). */\n blockedCidrs: string[];\n}\n\n/**\n * Validate a URL: allow iff (host in allowedHosts) AND (host not in blockedHosts). Then check blockedCidrs on resolved IP.\n *\n * @throws HTTP_DISALLOWED_HOST if the URL is blocked\n */\nexport async function validateUrl(url: string, options: ValidateUrlOptions): Promise<URL> {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Invalid URL: ${url}`,\n { url },\n );\n }\n\n // Only allow http/https\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Protocol not allowed: ${parsed.protocol}. Only http: and https: are supported.`,\n { url, protocol: parsed.protocol },\n );\n }\n\n const hostname = parsed.hostname;\n\n if (!isHostAllowed(hostname, options.allowedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is not in the allowed hosts list`,\n { url, hostname, allowedHosts: options.allowedHosts },\n );\n }\n if (isHostBlocked(hostname, options.blockedHosts)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" is in the blocked hosts list`,\n { url, hostname, blockedHosts: options.blockedHosts },\n );\n }\n\n // DNS resolve and check against blocked CIDRs\n try {\n const { address } = await lookup(hostname);\n if (isIpInBlockedCidrs(address, options.blockedCidrs)) {\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `Host \"${hostname}\" resolves to blocked IP: ${address}`,\n { url, hostname, resolvedIp: address },\n );\n }\n } catch (err) {\n // Re-throw our tagged errors\n if (err instanceof Error && (err as any).kind === \"HTTP_DISALLOWED_HOST\") {\n throw err;\n }\n // DNS resolution failure — block by default\n throw createTaggedError(\n \"HTTP_DISALLOWED_HOST\",\n `DNS resolution failed for host \"${hostname}\": ${err instanceof Error ? err.message : String(err)}`,\n { url, hostname },\n );\n }\n\n return parsed;\n}\n\n/**\n * Check if a hostname matches any entry in the allowed hosts list.\n * Supports: exact \"*\" (allow any host), wildcard prefix (e.g. \"*.github.com\"), or exact host.\n */\nfunction isHostAllowed(hostname: string, allowedHosts: string[]): boolean {\n for (const pattern of allowedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1); // \".github.com\"\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a hostname matches any entry in the blocked hosts list (same pattern rules as allowlist).\n */\nfunction isHostBlocked(hostname: string, blockedHosts: string[]): boolean {\n for (const pattern of blockedHosts) {\n if (pattern === \"*\") {\n return true;\n }\n if (pattern.startsWith(\"*.\")) {\n const suffix = pattern.slice(1);\n if (hostname.endsWith(suffix) || hostname === pattern.slice(2)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if an IPv4 address falls within any blocked CIDR range.\n */\nexport function isIpInBlockedCidrs(ip: string, cidrs: string[]): boolean {\n // Handle IPv4-mapped IPv6\n const normalizedIp = normalizeIp(ip);\n if (!normalizedIp) return false;\n\n for (const cidr of cidrs) {\n if (cidr.includes(\":\")) {\n // IPv6 CIDR — skip for IPv4 addresses\n if (!ip.includes(\":\")) continue;\n if (isIpv6InCidr(ip, cidr)) return true;\n } else {\n if (isIpv4InCidr(normalizedIp, cidr)) return true;\n }\n }\n return false;\n}\n\nfunction normalizeIp(ip: string): string | null {\n // Handle IPv4-mapped IPv6 (e.g. \"::ffff:127.0.0.1\")\n if (ip.startsWith(\"::ffff:\")) {\n return ip.slice(7);\n }\n // Pure IPv4\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(ip)) {\n return ip;\n }\n return null;\n}\n\nfunction isIpv4InCidr(ip: string, cidr: string): boolean {\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix) || prefix < 0 || prefix > 32) return false;\n\n const ipNum = ipv4ToNum(ip);\n const cidrNum = ipv4ToNum(cidrIp);\n if (ipNum === null || cidrNum === null) return false;\n\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0;\n return (ipNum & mask) === (cidrNum & mask);\n}\n\nfunction ipv4ToNum(ip: string): number | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let num = 0;\n for (const part of parts) {\n const n = parseInt(part, 10);\n if (isNaN(n) || n < 0 || n > 255) return null;\n num = (num << 8) | n;\n }\n return num >>> 0;\n}\n\nfunction isIpv6InCidr(ip: string, cidr: string): boolean {\n // Simplified IPv6 CIDR matching for common cases (::1, fc00::, fe80::)\n const [cidrIp, prefixStr] = cidr.split(\"/\");\n if (!cidrIp || !prefixStr) return false;\n\n const prefix = parseInt(prefixStr, 10);\n if (isNaN(prefix)) return false;\n\n const ipBytes = expandIpv6(ip);\n const cidrBytes = expandIpv6(cidrIp);\n if (!ipBytes || !cidrBytes) return false;\n\n // Compare prefix bits\n const fullBytes = Math.floor(prefix / 8);\n for (let i = 0; i < fullBytes && i < 16; i++) {\n if (ipBytes[i] !== cidrBytes[i]) return false;\n }\n\n const remainingBits = prefix % 8;\n if (remainingBits > 0 && fullBytes < 16) {\n const mask = (~0 << (8 - remainingBits)) & 0xff;\n if ((ipBytes[fullBytes]! & mask) !== (cidrBytes[fullBytes]! & mask)) return false;\n }\n\n return true;\n}\n\nfunction expandIpv6(ip: string): number[] | null {\n // Remove zone ID\n const zoneIdx = ip.indexOf(\"%\");\n if (zoneIdx !== -1) ip = ip.slice(0, zoneIdx);\n\n const parts = ip.split(\"::\");\n if (parts.length > 2) return null;\n\n const bytes: number[] = new Array(16).fill(0);\n\n const expandGroup = (group: string): number[] => {\n if (!group) return [];\n return group.split(\":\").flatMap((hex) => {\n const val = parseInt(hex || \"0\", 16);\n return [(val >> 8) & 0xff, val & 0xff];\n });\n };\n\n if (parts.length === 1) {\n const expanded = expandGroup(parts[0]!);\n if (expanded.length !== 16) return null;\n return expanded;\n }\n\n const left = expandGroup(parts[0]!);\n const right = expandGroup(parts[1]!);\n\n if (left.length + right.length > 16) return null;\n\n for (let i = 0; i < left.length; i++) bytes[i] = left[i]!;\n for (let i = 0; i < right.length; i++) bytes[16 - right.length + i] = right[i]!;\n\n return bytes;\n}\n"]}
@@ -1717,8 +1717,6 @@ function buildInputSchemaHint(inputSchema) {
1717
1717
  if (names.length === 0) return null;
1718
1718
  return `This tool expects input property ${names.length === 1 ? `'${names[0]}'` : `one of [${names.map((n) => `'${n}'`).join(", ")}]`}. Use the exact property names from the tool schema.`;
1719
1719
  }
1720
-
1721
- // src/api/runtimeFromConfig.ts
1722
1720
  var requireFromPackage = createRequire(import.meta.url);
1723
1721
  function getProjectRequire() {
1724
1722
  const cwd = process.cwd();
@@ -1736,7 +1734,6 @@ function findNearestPackageJson(startDir) {
1736
1734
  dir = parent;
1737
1735
  }
1738
1736
  }
1739
- var DEFAULT_EXTENSION_PACKAGES = [];
1740
1737
  function getInstalledPackageVersion(packageName) {
1741
1738
  const projectRequire = getProjectRequire();
1742
1739
  const requirers = [requireFromPackage];
@@ -1838,33 +1835,6 @@ function createLocalDirectoryAdapter(kind) {
1838
1835
  }
1839
1836
  };
1840
1837
  }
1841
- function resolveFileDescriptorPath(descriptor, configFilePath) {
1842
- const parsed = parseToolPath(descriptor.trim());
1843
- if (!parsed || parsed.protocol !== "file") return null;
1844
- const localPath = isAbsolute(configFilePath) ? configFilePath : resolve(process.cwd(), configFilePath);
1845
- const configDir = dirname(localPath);
1846
- return resolve(configDir, `${parsed.scope}/${parsed.packageWithVersion}`);
1847
- }
1848
- function getRegisterFn(mod) {
1849
- return mod?.register ?? mod?.registerCoreTools;
1850
- }
1851
- function loadExtensionFromNodeModules() {
1852
- const projectRequire = getProjectRequire();
1853
- const requirers = [requireFromPackage];
1854
- if (projectRequire) requirers.push(projectRequire);
1855
- for (const req of requirers) {
1856
- for (const pkg of DEFAULT_EXTENSION_PACKAGES) {
1857
- try {
1858
- const mod = req(pkg);
1859
- const fn = getRegisterFn(mod);
1860
- if (typeof fn === "function") return { register: fn, packageName: pkg };
1861
- } catch {
1862
- continue;
1863
- }
1864
- }
1865
- }
1866
- return null;
1867
- }
1868
1838
  function createPrefixingRegistry(registry, prefix) {
1869
1839
  return {
1870
1840
  register(spec) {
@@ -1911,6 +1881,37 @@ function parseNpmDescriptor(entry) {
1911
1881
  const version = rest.slice(at + 1).split("#")[0]?.trim() || "latest";
1912
1882
  return { packageName, version };
1913
1883
  }
1884
+
1885
+ // src/api/runtimeFromConfig.ts
1886
+ var requireFromPackage2 = createRequire(import.meta.url);
1887
+ var DEFAULT_EXTENSION_PACKAGES = [];
1888
+ function resolveFileDescriptorPath(descriptor, configFilePath) {
1889
+ const parsed = parseToolPath(descriptor.trim());
1890
+ if (!parsed || parsed.protocol !== "file") return null;
1891
+ const localPath = isAbsolute(configFilePath) ? configFilePath : resolve(process.cwd(), configFilePath);
1892
+ const configDir = dirname(localPath);
1893
+ return resolve(configDir, `${parsed.scope}/${parsed.packageWithVersion}`);
1894
+ }
1895
+ function getRegisterFn(mod) {
1896
+ return mod?.register ?? mod?.registerCoreTools;
1897
+ }
1898
+ function loadExtensionFromNodeModules() {
1899
+ const projectRequire = getProjectRequire();
1900
+ const requirers = [requireFromPackage2];
1901
+ if (projectRequire) requirers.push(projectRequire);
1902
+ for (const req of requirers) {
1903
+ for (const pkg of DEFAULT_EXTENSION_PACKAGES) {
1904
+ try {
1905
+ const mod = req(pkg);
1906
+ const fn = getRegisterFn(mod);
1907
+ if (typeof fn === "function") return { register: fn, packageName: pkg };
1908
+ } catch {
1909
+ continue;
1910
+ }
1911
+ }
1912
+ }
1913
+ return null;
1914
+ }
1914
1915
  function loadExtensionFromFileDescriptorSync(descriptor, configFilePath, stepLog) {
1915
1916
  const entryStr = descriptor.trim();
1916
1917
  const path = parseToolPath(entryStr);
@@ -2384,18 +2385,18 @@ var BodyParseError = class extends Error {
2384
2385
  }
2385
2386
  };
2386
2387
  function parseBody(req) {
2387
- return new Promise((resolve3, reject) => {
2388
+ return new Promise((resolve4, reject) => {
2388
2389
  const chunks = [];
2389
2390
  req.on("data", (chunk) => chunks.push(chunk));
2390
2391
  req.on("end", () => {
2391
2392
  const raw = Buffer.concat(chunks).toString("utf-8");
2392
2393
  if (!raw.trim()) {
2393
- resolve3({});
2394
+ resolve4({});
2394
2395
  return;
2395
2396
  }
2396
2397
  const parsed = safeParseToolArgs(raw);
2397
2398
  if (parsed.ok) {
2398
- resolve3(parsed.value);
2399
+ resolve4(parsed.value);
2399
2400
  return;
2400
2401
  }
2401
2402
  reject(new BodyParseError("Invalid JSON body", parsed.hint));
@@ -2553,13 +2554,13 @@ function createOpenAPIHttpServer(runtime, options = {}) {
2553
2554
  return server;
2554
2555
  }
2555
2556
  function listenOpenAPIHttpServer(server, options = {}) {
2556
- return new Promise((resolve3, reject) => {
2557
+ return new Promise((resolve4, reject) => {
2557
2558
  const port = options.port ?? 0;
2558
2559
  const host = options.host ?? "localhost";
2559
2560
  server.listen(port, host, () => {
2560
2561
  const addr = server.address();
2561
2562
  const actualPort = typeof addr === "object" && addr?.port != null ? addr.port : port;
2562
- resolve3({ port: actualPort, host });
2563
+ resolve4({ port: actualPort, host });
2563
2564
  });
2564
2565
  server.on("error", reject);
2565
2566
  });
@@ -2694,11 +2695,11 @@ async function createMCPServerStreamableHttp(runtimeOrConfig, options = {}) {
2694
2695
  async listen(listenPort, listenHost) {
2695
2696
  const p = listenPort ?? port;
2696
2697
  const h = listenHost ?? host;
2697
- return new Promise((resolve3, reject) => {
2698
+ return new Promise((resolve4, reject) => {
2698
2699
  const server = app.listen(p, h, () => {
2699
2700
  const addr = server.address();
2700
2701
  const actualPort = typeof addr === "object" && addr !== null && "port" in addr ? addr.port : p;
2701
- resolve3({ url: `http://${h}:${actualPort}${path}`, port: actualPort });
2702
+ resolve4({ url: `http://${h}:${actualPort}${path}`, port: actualPort });
2702
2703
  });
2703
2704
  });
2704
2705
  }
@@ -2711,5 +2712,5 @@ async function runMCPServerOverStdio(runtime, options = {}) {
2711
2712
  }
2712
2713
 
2713
2714
  export { PTCRuntime, createHttpService, createMCPServer, createMCPServerStreamableHttp, createMCPStreamableHttpHandler, createRuntimeFromConfig, createRuntimeFromConfigSync, expandToolDescriptorsToRegistryNames, fileDescriptorToPackagePrefix, findAndLoadToolConfig, getDisplayScope, isBarePackageDescriptor, loadToolConfig, npmDescriptorToPackagePrefixWithVersion, resolveSandboxedPath, resolveToolDescriptor, runMCPServerOverStdio };
2714
- //# sourceMappingURL=chunk-NVT4X4CB.js.map
2715
- //# sourceMappingURL=chunk-NVT4X4CB.js.map
2715
+ //# sourceMappingURL=chunk-RJAF5XY6.js.map
2716
+ //# sourceMappingURL=chunk-RJAF5XY6.js.map