fix(web-tools): land #31176 allow RFC2544 trusted fetch range (@sunkinux)
Landed from contributor PR #31176 by @sunkinux. Co-authored-by: sunkinux <sunkinux@users.noreply.github.com>
This commit is contained in:
@@ -113,6 +113,7 @@ Docs: https://docs.openclaw.ai
|
||||
- OpenAI Responses/Compaction: rewrite and unify the OpenAI Responses store patches to treat empty `baseUrl` as non-direct, honor `compat.supportsStore=false`, and auto-inject server-side compaction `context_management` for compatible direct OpenAI models (with per-model opt-out/threshold overrides). Landed from contributor PRs #16930 (@OiPunk), #22441 (@EdwardWu7), and #25088 (@MoerAI). Thanks @OiPunk, @EdwardWu7, and @MoerAI.
|
||||
- Signal/Sync message null-handling: treat `syncMessage` presence (including `null`) as sync envelope traffic so replayed sentTranscript payloads cannot bypass loop guards after daemon restart. Landed from contributor PR #31138 by @Sid-Qin. Thanks @Sid-Qin.
|
||||
- Inbound metadata/Multi-account routing: include `account_id` in trusted inbound metadata so multi-account channel sessions can reliably disambiguate the receiving account in prompt context. Landed from contributor PR #30984 by @Stxle2. Thanks @Stxle2.
|
||||
- Web tools/RFC2544 fake-IP compatibility: allow RFC2544 benchmark range (`198.18.0.0/15`) for trusted web-tool fetch endpoints so proxy fake-IP networking modes do not trigger false SSRF blocks. Landed from contributor PR #31176 by @sunkinux. Thanks @sunkinux.
|
||||
- Feishu/System preview prompt leakage: stop enqueuing inbound Feishu message previews as system events so user preview text is not injected into later turns as trusted `System:` context. Landed from contributor PR #31209 by @stakeswky. Thanks @stakeswky.
|
||||
- Feishu/Multi-account + reply reliability: add `channels.feishu.defaultAccount` outbound routing support with schema validation, keep quoted-message extraction text-first (post/interactive/file placeholders instead of raw JSON), route Feishu video sends as `msg_type: "file"`, and avoid websocket event blocking by using non-blocking event handling in monitor dispatch. Landed from contributor PRs #29610, #30432, #30331, and #29501. Thanks @hclsys, @bmendonca3, @patrick-yingxi-pan, and @zwffff.
|
||||
## Unreleased
|
||||
|
||||
51
src/agents/tools/web-guarded-fetch.test.ts
Normal file
51
src/agents/tools/web-guarded-fetch.test.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { fetchWithSsrFGuard } from "../../infra/net/fetch-guard.js";
|
||||
import { withStrictWebToolsEndpoint, withTrustedWebToolsEndpoint } from "./web-guarded-fetch.js";
|
||||
|
||||
vi.mock("../../infra/net/fetch-guard.js", () => ({
|
||||
fetchWithSsrFGuard: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("web-guarded-fetch", () => {
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("uses trusted SSRF policy for trusted web tools endpoints", async () => {
|
||||
vi.mocked(fetchWithSsrFGuard).mockResolvedValue({
|
||||
response: new Response("ok", { status: 200 }),
|
||||
finalUrl: "https://example.com",
|
||||
release: async () => {},
|
||||
});
|
||||
|
||||
await withTrustedWebToolsEndpoint({ url: "https://example.com" }, async () => undefined);
|
||||
|
||||
expect(fetchWithSsrFGuard).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
url: "https://example.com",
|
||||
policy: expect.objectContaining({
|
||||
dangerouslyAllowPrivateNetwork: true,
|
||||
allowRfc2544BenchmarkRange: true,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps strict endpoint policy unchanged", async () => {
|
||||
vi.mocked(fetchWithSsrFGuard).mockResolvedValue({
|
||||
response: new Response("ok", { status: 200 }),
|
||||
finalUrl: "https://example.com",
|
||||
release: async () => {},
|
||||
});
|
||||
|
||||
await withStrictWebToolsEndpoint({ url: "https://example.com" }, async () => undefined);
|
||||
|
||||
expect(fetchWithSsrFGuard).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
url: "https://example.com",
|
||||
}),
|
||||
);
|
||||
const call = vi.mocked(fetchWithSsrFGuard).mock.calls[0]?.[0];
|
||||
expect(call?.policy).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,7 @@ import type { SsrFPolicy } from "../../infra/net/ssrf.js";
|
||||
|
||||
const WEB_TOOLS_TRUSTED_NETWORK_SSRF_POLICY: SsrFPolicy = {
|
||||
dangerouslyAllowPrivateNetwork: true,
|
||||
allowRfc2544BenchmarkRange: true,
|
||||
};
|
||||
|
||||
type WebToolGuardedFetchOptions = Omit<GuardedFetchOptions, "proxy"> & {
|
||||
|
||||
@@ -955,8 +955,8 @@ describe("resolveOutboundSessionRoute", () => {
|
||||
target: "12345",
|
||||
threadId: "12345:99",
|
||||
expected: {
|
||||
sessionKey: "agent:main:telegram:direct:12345",
|
||||
from: "telegram:12345",
|
||||
sessionKey: "agent:main:telegram:direct:12345:thread:99",
|
||||
from: "telegram:12345:topic:99",
|
||||
to: "telegram:12345",
|
||||
threadId: 99,
|
||||
chatType: "direct",
|
||||
|
||||
Reference in New Issue
Block a user