@xpr-agents/openclaw 0.8.1 → 0.8.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"a2a.d.ts","sourceRoot":"","sources":["../../src/tools/a2a.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA8DxD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA2M3E"}
1
+ {"version":3,"file":"a2a.d.ts","sourceRoot":"","sources":["../../src/tools/a2a.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAkFxD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAqN3E"}
package/dist/tools/a2a.js CHANGED
@@ -13,6 +13,7 @@ exports.registerA2ATools = registerA2ATools;
13
13
  const sdk_1 = require("@xpr-agents/sdk");
14
14
  const validate_1 = require("../util/validate");
15
15
  const confirm_1 = require("../util/confirm");
16
+ const ssrf_1 = require("../util/ssrf");
16
17
  /** Look up an agent's endpoint from the on-chain registry */
17
18
  async function resolveEndpoint(rpc, contracts, account) {
18
19
  const result = await rpc.get_table_rows({
@@ -34,8 +35,28 @@ async function resolveEndpoint(rpc, contracts, account) {
34
35
  if (!agent.endpoint) {
35
36
  throw new Error(`Agent '${account}' has no endpoint configured`);
36
37
  }
38
+ // SSRF: the endpoint is attacker-controlled (on-chain check is scheme/length
39
+ // only). Refuse private/internal targets before any outbound fetch. Note: the
40
+ // A2AClient still follows redirects, so a public host that 3xx-redirects to an
41
+ // internal one is a residual (tracked) — this blocks the direct-registration case.
42
+ await (0, ssrf_1.assertPublicHttpUrl)(agent.endpoint);
37
43
  return agent.endpoint;
38
44
  }
45
+ // Network chain id, bound into the A2A signed digest (codex #8) so a signature
46
+ // cannot be replayed across networks. Fetched once via get_info and cached.
47
+ let cachedChainId = null;
48
+ async function getChainId(rpc) {
49
+ if (cachedChainId)
50
+ return cachedChainId;
51
+ if (!rpc.get_info)
52
+ throw new Error('RPC client does not support get_info (needed for A2A chain-id binding)');
53
+ const info = await rpc.get_info();
54
+ const id = info.chain_id;
55
+ if (!id)
56
+ throw new Error('Could not determine chain id from RPC get_info');
57
+ cachedChainId = id;
58
+ return id;
59
+ }
39
60
  // Signing key for A2A request authentication.
40
61
  //
41
62
  // Reads `A2A_SIGNING_KEY` (NOT `XPR_PRIVATE_KEY`) — A2A uses a separate
@@ -78,6 +99,8 @@ function registerA2ATools(api, config) {
78
99
  const client = new sdk_1.A2AClient(endpoint, {
79
100
  callerAccount: config.session?.auth.actor,
80
101
  signingKey,
102
+ targetAccount: account,
103
+ chainId: await getChainId(config.rpc),
81
104
  });
82
105
  return client.getAgentCard();
83
106
  },
@@ -106,6 +129,8 @@ function registerA2ATools(api, config) {
106
129
  const client = new sdk_1.A2AClient(endpoint, {
107
130
  callerAccount: config.session?.auth.actor,
108
131
  signingKey,
132
+ targetAccount: account,
133
+ chainId: await getChainId(config.rpc),
109
134
  });
110
135
  const message = {
111
136
  role: 'user',
@@ -138,6 +163,8 @@ function registerA2ATools(api, config) {
138
163
  const client = new sdk_1.A2AClient(endpoint, {
139
164
  callerAccount: config.session?.auth.actor,
140
165
  signingKey,
166
+ targetAccount: account,
167
+ chainId: await getChainId(config.rpc),
141
168
  });
142
169
  return client.getTask(task_id);
143
170
  },
@@ -162,6 +189,8 @@ function registerA2ATools(api, config) {
162
189
  const client = new sdk_1.A2AClient(endpoint, {
163
190
  callerAccount: config.session?.auth.actor,
164
191
  signingKey,
192
+ targetAccount: account,
193
+ chainId: await getChainId(config.rpc),
165
194
  });
166
195
  return client.cancelTask(task_id);
167
196
  },
@@ -210,6 +239,8 @@ function registerA2ATools(api, config) {
210
239
  const client = new sdk_1.A2AClient(endpoint, {
211
240
  callerAccount: config.session?.auth.actor,
212
241
  signingKey,
242
+ targetAccount: account,
243
+ chainId: await getChainId(config.rpc),
213
244
  });
214
245
  const text = [
215
246
  `# Job Delegation: ${job.title}`,
@@ -1 +1 @@
1
- {"version":3,"file":"a2a.js","sourceRoot":"","sources":["../../src/tools/a2a.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAkEH,4CA2MC;AA3QD,yCAA4C;AAG5C,+CAAuD;AACvD,6CAAoD;AAEpD,6DAA6D;AAC7D,KAAK,UAAU,eAAe,CAC5B,GAAwB,EACxB,SAAoC,EACpC,OAAe;IAEf,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,cAAc,CAAuC;QAC5E,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,SAAS,CAAC,SAAS;QACzB,KAAK,EAAE,SAAS,CAAC,SAAS;QAC1B,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,OAAO;QACpB,WAAW,EAAE,OAAO;QACpB,KAAK,EAAE,CAAC;KACT,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,sBAAsB,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,iBAAiB,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,8BAA8B,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC;AAED,8CAA8C;AAC9C,EAAE;AACF,wEAAwE;AACxE,uEAAuE;AACvE,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,4CAA4C;AAC5C,yEAAyE;AACzE,oEAAoE;AACpE,2EAA2E;AAC3E,yEAAyE;AACzE,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,4BAA4B;AAC5B,EAAE;AACF,0CAA0C;AAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AAC/C,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;IAC3C,OAAO,CAAC,IAAI,CACV,sEAAsE;QACtE,4BAA4B,CAC7B,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,GAAc,EAAE,MAAoB;IACnE,iEAAiE;IACjE,GAAG,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,2JAA2J;QACxK,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,SAAS,CAAC;YACrB,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2CAA2C,EAAE;aACtF;SACF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAuB,EAAE,EAAE;YAClD,IAAA,8BAAmB,EAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,IAAI,eAAS,CAAC,QAAQ,EAAE;gBACrC,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK;gBACzC,UAAU;aACX,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,YAAY,EAAE,CAAC;QAC/B,CAAC;KACF,CAAC,CAAC;IAEH,iEAAiE;IACjE,GAAG,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,gJAAgJ;QAC7J,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;YAC7B,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;gBAChF,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;gBAC7D,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACnF,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;gBACvF,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;aAC5E;SACF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAM3D,EAAE,EAAE;YACH,IAAA,8BAAmB,EAAC,OAAO,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACtC,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,IAAI,eAAS,CAAC,QAAQ,EAAE;gBACrC,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK;gBACzC,UAAU;aACX,CAAC,CAAC;YAEH,MAAM,OAAO,GAAe;gBAC1B,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aAChC,CAAC;YAEF,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE;gBACjC,MAAM,EAAE,OAAO;gBACf,SAAS,EAAE,UAAU;gBACrB,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;IAEH,iEAAiE;IACjE,GAAG,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,0GAA0G;QACvH,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;YAChC,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gDAAgD,EAAE;gBAC1F,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;aAC/D;SACF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAwC,EAAE,EAAE;YAC5E,IAAA,8BAAmB,EAAC,OAAO,CAAC,CAAC;YAC7B,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAErD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,IAAI,eAAS,CAAC,QAAQ,EAAE;gBACrC,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK;gBACzC,UAAU;aACX,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;KACF,CAAC,CAAC;IAEH,iEAAiE;IACjE,GAAG,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,8CAA8C;QAC3D,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;YAChC,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gDAAgD,EAAE;gBAC1F,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;aAC9D;SACF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAwC,EAAE,EAAE;YAC5E,IAAA,8BAAmB,EAAC,OAAO,CAAC,CAAC;YAC7B,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAErD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,IAAI,eAAS,CAAC,QAAQ,EAAE;gBACrC,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK;gBACzC,UAAU;aACX,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;KACF,CAAC,CAAC;IAEH,iEAAiE;IACjE,GAAG,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,0NAA0N;QACvO,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC;YAC/C,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8CAA8C,EAAE;gBACxF,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;gBACpE,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;gBACrF,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,kCAAkC,EAAE;aAChF;SACF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAKzD,EAAE,EAAE;YACH,IAAA,8BAAmB,EAAC,OAAO,CAAC,CAAC;YAC7B,IAAI,MAAM,IAAI,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACjD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;gBACtD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,CAAC;YAED,oBAAoB;YACpB,MAAM,YAAY,GAAG,IAAA,2BAAiB,EACpC,MAAM,CAAC,eAAe,EACtB,SAAS,EACT,sBAAsB,EACtB,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,EAAE,EACnF,aAAa,MAAM,uCAAuC,OAAO,WAAW,CAC7E,CAAC;YACF,IAAI,YAAY;gBAAE,OAAO,YAAY,CAAC;YAEtC,yCAAyC;YACzC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAG9C;gBACD,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW;gBAClC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW;gBACnC,KAAK,EAAE,MAAM;gBACb,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC;gBAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC;gBAC3B,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;YAEH,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,YAAY,CAAC,CAAC;YAC9C,CAAC;YAED,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,IAAI,eAAS,CAAC,QAAQ,EAAE;gBACrC,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK;gBACzC,UAAU;aACX,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG;gBACX,qBAAqB,GAAG,CAAC,KAAK,EAAE;gBAChC,EAAE;gBACF,eAAe,GAAG,CAAC,EAAE,EAAE;gBACvB,oBAAoB,GAAG,CAAC,WAAW,EAAE;gBACrC,qBAAqB,GAAG,CAAC,YAAY,EAAE;gBACvC,eAAe,GAAG,CAAC,MAAM,MAAM;gBAC/B,iBAAiB,GAAG,CAAC,QAAQ,EAAE;gBAC/B,EAAE;gBACF,iBAAiB;gBACjB,YAAY;aACb,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,OAAO,GAAe;gBAC1B,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aAChC,CAAC;YAEF,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACxD,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"a2a.js","sourceRoot":"","sources":["../../src/tools/a2a.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function isPrivateAddress(ip: string): boolean;
2
+ /** Throw unless `urlStr` is an http(s) URL whose host resolves only to public addresses. */
3
+ export declare function assertPublicHttpUrl(urlStr: string): Promise<void>;
4
+ //# sourceMappingURL=ssrf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.d.ts","sourceRoot":"","sources":["../../src/util/ssrf.ts"],"names":[],"mappings":"AAaA,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CA4BpD;AAED,4FAA4F;AAC5F,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBvE"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPrivateAddress = isPrivateAddress;
4
+ exports.assertPublicHttpUrl = assertPublicHttpUrl;
5
+ /**
6
+ * SSRF guard for outbound A2A discovery/calls.
7
+ *
8
+ * An agent's A2A endpoint is attacker-controlled: anyone can register an agent
9
+ * on-chain with `endpoint: "http://127.0.0.1:port"` or a public host that
10
+ * redirects to an internal one, and the on-chain check only validates the URL
11
+ * scheme/length. Discovering such an agent makes this process fetch the internal
12
+ * target. Resolve the host and refuse any private/loopback/link-local/ULA/CGNAT/
13
+ * metadata address before we hand the endpoint to the A2A client.
14
+ */
15
+ const promises_1 = require("node:dns/promises");
16
+ const node_net_1 = require("node:net");
17
+ function isPrivateAddress(ip) {
18
+ const v = (0, node_net_1.isIP)(ip);
19
+ if (v === 4) {
20
+ const p = ip.split('.').map(Number);
21
+ if (p.length !== 4 || p.some(n => Number.isNaN(n)))
22
+ return true;
23
+ const [a, b, c] = p;
24
+ return (a === 0 || a === 10 || a === 127 ||
25
+ (a === 169 && b === 254) ||
26
+ (a === 172 && b >= 16 && b <= 31) ||
27
+ (a === 192 && b === 168) ||
28
+ (a === 192 && b === 0 && c === 0) ||
29
+ (a === 198 && (b === 18 || b === 19)) ||
30
+ (a === 100 && b >= 64 && b <= 127) ||
31
+ a >= 224);
32
+ }
33
+ if (v === 6) {
34
+ const s = ip.toLowerCase();
35
+ return (s === '::1' || s === '::' ||
36
+ s.startsWith('::ffff:') ||
37
+ s.startsWith('64:ff9b') ||
38
+ /^fe[89a-f]/.test(s) ||
39
+ s.startsWith('fc') || s.startsWith('fd'));
40
+ }
41
+ return true;
42
+ }
43
+ /** Throw unless `urlStr` is an http(s) URL whose host resolves only to public addresses. */
44
+ async function assertPublicHttpUrl(urlStr) {
45
+ let host;
46
+ try {
47
+ const u = new URL(urlStr);
48
+ if (u.protocol !== 'http:' && u.protocol !== 'https:') {
49
+ throw new Error(`endpoint must be http(s), got ${u.protocol}`);
50
+ }
51
+ host = u.hostname;
52
+ }
53
+ catch (e) {
54
+ throw new Error(`invalid endpoint URL: ${e.message}`);
55
+ }
56
+ if ((0, node_net_1.isIP)(host)) {
57
+ if (isPrivateAddress(host))
58
+ throw new Error(`endpoint resolves to a non-public address: ${host}`);
59
+ return;
60
+ }
61
+ let addrs;
62
+ try {
63
+ addrs = await (0, promises_1.lookup)(host, { all: true });
64
+ }
65
+ catch {
66
+ throw new Error(`endpoint host does not resolve: ${host}`);
67
+ }
68
+ if (addrs.length === 0 || addrs.some(a => isPrivateAddress(a.address))) {
69
+ throw new Error(`endpoint host resolves to a non-public address: ${host}`);
70
+ }
71
+ }
72
+ //# sourceMappingURL=ssrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../src/util/ssrf.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpr-agents/openclaw",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "OpenClaw plugin for XPR Network Trustless Agent Registry - autonomous agent operation, escrow jobs, feedback, and validation",
5
5
  "author": "XPR Network",
6
6
  "bin": {
@@ -46,14 +46,14 @@
46
46
  "prepublishOnly": "npm run clean && npm run build"
47
47
  },
48
48
  "dependencies": {
49
- "@xpr-agents/sdk": "^0.4.0",
49
+ "@xpr-agents/sdk": "^0.5.0",
50
50
  "@proton/js": "^28.1.2",
51
51
  "@shellbook/sdk": "^0.2.4"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^20.0.0",
55
55
  "typescript": "^5.0.0",
56
- "vitest": "^1.0.0"
56
+ "vitest": "^4.1.11"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">=18.0.0"
@@ -15,60 +15,75 @@ const DEFAULT_TIMEOUT = 5000;
15
15
  const MAX_TIMEOUT = 30000;
16
16
  const MAX_OUTPUT_SIZE = 10 * 1024 * 1024; // 10MB
17
17
  // ── Sandbox helpers ─────────────────────────────
18
- function createSandboxGlobals(input, logs) {
19
- // Capture console methods
20
- const consoleMock = {
21
- log: (...args) => {
22
- logs.push(args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
23
- },
24
- warn: (...args) => {
25
- logs.push('[warn] ' + args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
26
- },
27
- error: (...args) => {
28
- logs.push('[error] ' + args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
29
- },
30
- };
31
- return {
32
- INPUT: input,
33
- console: consoleMock,
34
- JSON,
35
- Math,
36
- Date,
37
- Array,
38
- Object,
39
- String,
40
- Number,
41
- RegExp,
42
- Map,
43
- Set,
44
- parseInt,
45
- parseFloat,
46
- isNaN,
47
- isFinite,
48
- encodeURIComponent,
49
- decodeURIComponent,
50
- atob: (s) => Buffer.from(s, 'base64').toString('binary'),
51
- btoa: (s) => Buffer.from(s, 'binary').toString('base64'),
52
- // Explicitly undefined — blocked
53
- require: undefined,
54
- process: undefined,
55
- globalThis: undefined,
56
- global: undefined,
57
- };
58
- }
59
- function serializeResult(value) {
60
- if (value === undefined)
61
- return 'undefined';
62
- try {
63
- const str = JSON.stringify(value, null, 2);
64
- if (str.length > MAX_OUTPUT_SIZE) {
65
- return str.slice(0, MAX_OUTPUT_SIZE) + '\n... [truncated at 10MB]';
66
- }
67
- return str;
68
- }
69
- catch {
70
- return String(value);
71
- }
18
+ //
19
+ // SECURITY: the context is given ONLY primitive strings — never a host function or
20
+ // object. That is the whole game with node:vm. `codeGeneration.strings:false` only
21
+ // disables eval/Function *for this context's own realm*; a host closure handed in
22
+ // (a console mock, atob/btoa via Buffer, anything) exposes `fn.constructor` — the
23
+ // HOST realm's Function, where code generation is still allowed — so
24
+ // `console.log.constructor("return process.env")()` would read the runner's secrets
25
+ // and `Object.getPrototypeOf(hostFn).constructor.prototype` would pollute the host.
26
+ // So: console, atob/btoa, INPUT parsing and the *result serialization* all run as
27
+ // sandbox-realm code (below). Serializing inside the sandbox also keeps it under the
28
+ // execution timeout — a malicious getter can no longer stall the host via a
29
+ // host-side JSON.stringify. The only value read back out is a JSON string (a
30
+ // primitive), which the host then parses safely.
31
+ /** Sandbox-realm preamble: pure-JS console/atob/btoa/INPUT, no host references. */
32
+ const SANDBOX_PREAMBLE = `
33
+ var __logs = [];
34
+ var console = {
35
+ log: function(){ __logs.push(Array.prototype.map.call(arguments, function(a){ return typeof a === 'object' ? JSON.stringify(a) : String(a); }).join(' ')); },
36
+ warn: function(){ __logs.push('[warn] ' + Array.prototype.map.call(arguments, function(a){ return typeof a === 'object' ? JSON.stringify(a) : String(a); }).join(' ')); },
37
+ error: function(){ __logs.push('[error] ' + Array.prototype.map.call(arguments, function(a){ return typeof a === 'object' ? JSON.stringify(a) : String(a); }).join(' ')); }
38
+ };
39
+ var __B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
40
+ function btoa(s){ s = String(s); var o = ''; for (var i = 0; i < s.length; ) {
41
+ var c1 = s.charCodeAt(i++), c2 = s.charCodeAt(i++), c3 = s.charCodeAt(i++);
42
+ var e1 = c1 >> 2, e2 = ((c1 & 3) << 4) | (c2 >> 4), e3 = ((c2 & 15) << 2) | (c3 >> 6), e4 = c3 & 63;
43
+ if (isNaN(c2)) { e3 = e4 = 64; } else if (isNaN(c3)) { e4 = 64; }
44
+ o += __B64.charAt(e1) + __B64.charAt(e2) + (e3 === 64 ? '=' : __B64.charAt(e3)) + (e4 === 64 ? '=' : __B64.charAt(e4));
45
+ } return o; }
46
+ function atob(s){ s = String(s).replace(/[^A-Za-z0-9+/=]/g, ''); var o = ''; for (var i = 0; i < s.length; ) {
47
+ var d1 = __B64.indexOf(s.charAt(i++)), d2 = __B64.indexOf(s.charAt(i++)), d3 = __B64.indexOf(s.charAt(i++)), d4 = __B64.indexOf(s.charAt(i++));
48
+ var c1 = (d1 << 2) | (d2 >> 4), c2 = ((d2 & 15) << 4) | (d3 >> 2), c3 = ((d3 & 3) << 6) | d4;
49
+ o += String.fromCharCode(c1); if (d3 !== 64 && d3 >= 0) o += String.fromCharCode(c2); if (d4 !== 64 && d4 >= 0) o += String.fromCharCode(c3);
50
+ } return o; }
51
+ `.trim();
52
+ /**
53
+ * Run a self-contained expression/body in a fresh vm realm and return the parsed
54
+ * outcome. `body` must be a statement list whose LAST expression is the user value
55
+ * to capture. Everything is serialized to a JSON string inside the sandbox.
56
+ */
57
+ function runInSandbox(body, timeoutMs, inputJson) {
58
+ // Only a primitive string crosses into the realm — AND the context global is
59
+ // given a NULL prototype. If we hand vm.createContext an ordinary host object,
60
+ // the sandbox global inherits the HOST realm's Object.prototype, so
61
+ // `this.constructor.constructor("return process.env")()` walks to the host
62
+ // Function (where codeGeneration is allowed) and reads the runner's secrets —
63
+ // codeGeneration:false only covers THIS context's realm. A null-proto global
64
+ // makes `this.constructor` resolve to the sandbox realm's own Function, which
65
+ // the flag then blocks. (Confirmed escape via the global-object path, 2026-09-19.)
66
+ const sandboxGlobal = Object.create(null);
67
+ sandboxGlobal.__INPUT_JSON = inputJson;
68
+ const context = vm_1.default.createContext(sandboxGlobal, {
69
+ codeGeneration: { strings: false, wasm: false },
70
+ });
71
+ const wrapped = `${SANDBOX_PREAMBLE}
72
+ var INPUT = (typeof __INPUT_JSON === 'string') ? JSON.parse(__INPUT_JSON) : undefined;
73
+ var __result, __error = null;
74
+ try { __result = (function(){ ${body} \n})(); } catch (e) { __error = (e && e.message) ? String(e.message) : String(e); }
75
+ (function(){
76
+ try { return JSON.stringify({ ok: __error === null, result: __result === undefined ? null : __result, logs: __logs, error: __error }); }
77
+ catch (e) { return JSON.stringify({ ok: __error === null, result: String(__result), logs: __logs, error: __error }); }
78
+ })();`;
79
+ const script = new vm_1.default.Script(wrapped, { filename: 'sandbox.js' });
80
+ const out = script.runInContext(context, { timeout: timeoutMs });
81
+ if (typeof out !== 'string')
82
+ return { ok: false, logs: [], error: 'sandbox produced no serializable output' };
83
+ if (out.length > MAX_OUTPUT_SIZE)
84
+ return { ok: false, logs: [], error: 'Output exceeded 10MB limit', oversized: true };
85
+ const parsed = JSON.parse(out);
86
+ return parsed;
72
87
  }
73
88
  // ── Skill entry point ───────────────────────────
74
89
  function codeSandboxSkill(api) {
@@ -97,48 +112,40 @@ function codeSandboxSkill(api) {
97
112
  return { error: 'code parameter is required and must be a string' };
98
113
  }
99
114
  const timeoutMs = Math.min(Math.max(timeout || DEFAULT_TIMEOUT, 100), MAX_TIMEOUT);
100
- const logs = [];
101
115
  const startTime = Date.now();
116
+ let inputJson;
102
117
  try {
103
- const globals = createSandboxGlobals(input, logs);
104
- const context = vm_1.default.createContext(globals, {
105
- codeGeneration: { strings: false, wasm: false },
106
- });
107
- // Wrap code so the last expression is returned
108
- const wrapped = `(function() {\n${code}\n})()`;
109
- const script = new vm_1.default.Script(wrapped, { filename: 'sandbox.js' });
110
- const result = script.runInContext(context, { timeout: timeoutMs });
118
+ inputJson = input === undefined ? undefined : JSON.stringify(input);
119
+ }
120
+ catch {
121
+ return { error: 'input could not be serialized to JSON' };
122
+ }
123
+ try {
124
+ const out = runInSandbox(code, timeoutMs, inputJson);
111
125
  const durationMs = Date.now() - startTime;
112
- const serialized = serializeResult(result);
113
- if (serialized.length > MAX_OUTPUT_SIZE) {
114
- return {
115
- result: serialized.slice(0, 1000) + '... [truncated]',
116
- logs,
117
- duration_ms: durationMs,
118
- warning: 'Output exceeded 10MB limit and was truncated',
119
- };
120
- }
121
- // Parse back to preserve types (arrays, objects)
122
- let parsed;
123
- try {
124
- parsed = JSON.parse(serialized);
126
+ if (out.oversized) {
127
+ return { error: 'Output exceeded 10MB limit', logs: out.logs, duration_ms: durationMs, warning: 'Output exceeded 10MB limit and was truncated' };
125
128
  }
126
- catch {
127
- parsed = serialized === 'undefined' ? undefined : serialized;
129
+ if (!out.ok) {
130
+ const message = out.error || 'unknown error';
131
+ if (message.includes('Code generation from strings disallowed')) {
132
+ return { error: 'eval() and Function() constructor are blocked in the sandbox. Use direct code instead.', logs: out.logs, duration_ms: durationMs };
133
+ }
134
+ return { error: message, logs: out.logs, duration_ms: durationMs };
128
135
  }
129
- return { result: parsed, logs, duration_ms: durationMs };
136
+ return { result: out.result, logs: out.logs, duration_ms: durationMs };
130
137
  }
131
138
  catch (err) {
132
139
  const durationMs = Date.now() - startTime;
133
140
  const message = err.message || String(err);
134
- // Provide helpful error context
135
- if (message.includes('Script execution timed out')) {
136
- return { error: `Execution timed out after ${timeoutMs}ms. Keep code efficient or increase timeout (max ${MAX_TIMEOUT}ms).`, logs, duration_ms: durationMs };
141
+ // Timeout is a hard interrupt thrown to the host, so it lands here.
142
+ if (message.includes('Script execution timed out') || message.includes('timed out')) {
143
+ return { error: `Execution timed out after ${timeoutMs}ms. Keep code efficient or increase timeout (max ${MAX_TIMEOUT}ms).`, logs: [], duration_ms: durationMs };
137
144
  }
138
145
  if (message.includes('Code generation from strings disallowed')) {
139
- return { error: 'eval() and Function() constructor are blocked in the sandbox. Use direct code instead.', logs, duration_ms: durationMs };
146
+ return { error: 'eval() and Function() constructor are blocked in the sandbox. Use direct code instead.', logs: [], duration_ms: durationMs };
140
147
  }
141
- return { error: message, logs, duration_ms: durationMs };
148
+ return { error: message, logs: [], duration_ms: durationMs };
142
149
  }
143
150
  },
144
151
  });
@@ -162,26 +169,20 @@ function codeSandboxSkill(api) {
162
169
  return { error: 'expression parameter is required and must be a string' };
163
170
  }
164
171
  try {
165
- const globals = createSandboxGlobals(undefined, []);
166
- const context = vm_1.default.createContext(globals, {
167
- codeGeneration: { strings: false, wasm: false },
168
- });
169
- const script = new vm_1.default.Script(`(${expression})`, { filename: 'expr.js' });
170
- const result = script.runInContext(context, { timeout: DEFAULT_TIMEOUT });
171
- let serialized;
172
- try {
173
- serialized = JSON.parse(JSON.stringify(result));
174
- }
175
- catch {
176
- serialized = String(result);
177
- }
178
- return {
179
- result: serialized,
180
- type: result === null ? 'null' : Array.isArray(result) ? 'array' : typeof result,
181
- };
172
+ // Evaluate as the returned value of the sandbox body (same isolated realm,
173
+ // in-sandbox serialization). The value comes back as parsed JSON.
174
+ const out = runInSandbox(`return (${expression});`, DEFAULT_TIMEOUT, undefined);
175
+ if (!out.ok)
176
+ return { error: out.error || 'evaluation failed' };
177
+ const r = out.result;
178
+ const type = r === null ? 'null' : Array.isArray(r) ? 'array' : typeof r;
179
+ return { result: r, type };
182
180
  }
183
181
  catch (err) {
184
- return { error: err.message || String(err) };
182
+ const message = err.message || String(err);
183
+ if (message.includes('timed out'))
184
+ return { error: `Execution timed out after ${DEFAULT_TIMEOUT}ms.` };
185
+ return { error: message };
185
186
  }
186
187
  },
187
188
  });