mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:10:45 +00:00
fix(bluebubbles): revert undici import, restore dispatcher-strip approach
Revert the @claude bot's undici import in types.ts — it introduced a direct 'undici' dependency that is not declared in the BB extension's package.json and would break isolated plugin installs. Restore the original dispatcher-strip approach which is correct: the SSRF guard already completed validation upstream before calling this function as fetchImpl, so stripping the dispatcher does not weaken security.
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/setup";
|
import type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/setup";
|
||||||
import { fetchWithSsrFGuard, type SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
import { fetchWithSsrFGuard, type SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||||
import { fetch as undiciFetch } from "undici";
|
|
||||||
|
|
||||||
export type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
export type { SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||||
export type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/setup";
|
export type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/setup";
|
||||||
@@ -176,26 +175,18 @@ export async function blueBubblesFetchWithTimeout(
|
|||||||
await release();
|
await release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The SSRF guard (and other guarded callers using this function as their
|
// Strip `dispatcher` from init — the SSRF guard may have attached a bundled-undici
|
||||||
// `fetchImpl`) may attach a bundled-undici `dispatcher` to `init` to enforce DNS
|
// dispatcher that is incompatible with Node 22+'s built-in undici backing globalThis.fetch().
|
||||||
// pinning per request. That dispatcher is incompatible with Node 22+'s built-in
|
// Passing it through causes a silent TypeError (invalid onRequestStart method).
|
||||||
// undici backing globalThis.fetch and causes a silent TypeError (invalid
|
// The SSRF validation already completed upstream in fetchWithSsrFGuard before calling
|
||||||
// onRequestStart method) when forwarded — but it works correctly with the
|
// this function as fetchImpl, so stripping the dispatcher does not weaken security. (#64105)
|
||||||
// bundled-undici `fetch`. When a dispatcher is present, route through bundled
|
const { dispatcher: _dispatcher, ...safeInit } = (init ?? {}) as RequestInit & {
|
||||||
// undici so the DNS-pinning contract is preserved; otherwise stay on
|
dispatcher?: unknown;
|
||||||
// globalThis.fetch. (#64105, #67510)
|
};
|
||||||
const initWithDispatcher = (init ?? {}) as RequestInit & { dispatcher?: unknown };
|
|
||||||
const hasDispatcher = initWithDispatcher.dispatcher !== undefined;
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
||||||
try {
|
try {
|
||||||
if (hasDispatcher) {
|
return await fetch(url, { ...safeInit, signal: controller.signal });
|
||||||
return (await undiciFetch(url, {
|
|
||||||
...initWithDispatcher,
|
|
||||||
signal: controller.signal,
|
|
||||||
} as Parameters<typeof undiciFetch>[1])) as unknown as Response;
|
|
||||||
}
|
|
||||||
return await fetch(url, { ...initWithDispatcher, signal: controller.signal });
|
|
||||||
} finally {
|
} finally {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user