From c2fb4007c24a0d8ead011a83a4e814630f73f052 Mon Sep 17 00:00:00 2001 From: Kagura Date: Sat, 18 Apr 2026 12:50:50 +0800 Subject: [PATCH] Matrix: forward dangerouslyAllowPrivateNetwork config to client SSRF policy (#68332) Merged via squash. Prepared head SHA: d8733928eb6baf743554f7ccc9e73d742c6c6efb Co-authored-by: kagura-agent <268167063+kagura-agent@users.noreply.github.com> Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com> Reviewed-by: @gumadeiras --- CHANGELOG.md | 1 + .../src/matrix/client/create-client.test.ts | 55 +++++++++++++++++++ .../matrix/src/matrix/client/create-client.ts | 8 ++- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6fde32e12d..35fed52ac1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Docs: https://docs.openclaw.ai - OpenAI Codex/OAuth + Pi: keep imported Codex CLI OAuth bootstrap, Pi auth export, and runtime overlay handling aligned so Codex sessions survive refresh and health checks without leaking transient CLI state into saved auth files. Thanks @vincentkoc. - Agents/TTS: report failed speech synthesis as a real tool error so unconfigured providers no longer feed successful TTS failure output back into agent loops. (#67980) Thanks @lawrence3699. - Gateway/wake: allow unknown properties on wake payloads so external senders like Paperclip can attach opaque metadata without failing schema validation. (#68355) Thanks @kagura-agent. +- Matrix: honor `channels.matrix.network.dangerouslyAllowPrivateNetwork` when creating clients for private-network homeservers. (#68332) Thanks @kagura-agent. ## 2026.4.15 diff --git a/extensions/matrix/src/matrix/client/create-client.test.ts b/extensions/matrix/src/matrix/client/create-client.test.ts index 4a2b28105a3..108ab0ce489 100644 --- a/extensions/matrix/src/matrix/client/create-client.test.ts +++ b/extensions/matrix/src/matrix/client/create-client.test.ts @@ -86,6 +86,61 @@ describe("createMatrixClient", () => { }); }); + it("derives ssrfPolicy from allowPrivateNetwork when no explicit policy is provided", async () => { + await createMatrixClient({ + homeserver: "https://matrix.example.org", + userId: "@bot:example.org", + accessToken: "tok", + persistStorage: false, + allowPrivateNetwork: true, + }); + + expect(MatrixClientMock).toHaveBeenCalledWith( + "https://matrix.example.org", + "tok", + expect.objectContaining({ + ssrfPolicy: { allowPrivateNetwork: true }, + }), + ); + }); + + it("prefers explicit ssrfPolicy over allowPrivateNetwork", async () => { + const explicitPolicy = { allowPrivateNetwork: true, customField: "test" }; + await createMatrixClient({ + homeserver: "https://matrix.example.org", + userId: "@bot:example.org", + accessToken: "tok", + persistStorage: false, + allowPrivateNetwork: false, + ssrfPolicy: explicitPolicy as never, + }); + + expect(MatrixClientMock).toHaveBeenCalledWith( + "https://matrix.example.org", + "tok", + expect.objectContaining({ + ssrfPolicy: explicitPolicy, + }), + ); + }); + + it("leaves ssrfPolicy undefined when allowPrivateNetwork is falsy and no explicit policy", async () => { + await createMatrixClient({ + homeserver: "https://matrix.example.org", + userId: "@bot:example.org", + accessToken: "tok", + persistStorage: false, + }); + + expect(MatrixClientMock).toHaveBeenCalledWith( + "https://matrix.example.org", + "tok", + expect.objectContaining({ + ssrfPolicy: undefined, + }), + ); + }); + it("skips persistent storage wiring when persistence is disabled", async () => { await createMatrixClient({ homeserver: "https://matrix.example.org", diff --git a/extensions/matrix/src/matrix/client/create-client.ts b/extensions/matrix/src/matrix/client/create-client.ts index c543308bd82..2b5a3948db5 100644 --- a/extensions/matrix/src/matrix/client/create-client.ts +++ b/extensions/matrix/src/matrix/client/create-client.ts @@ -1,7 +1,10 @@ import fs from "node:fs"; import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher"; import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime"; -import type { SsrFPolicy } from "../../runtime-api.js"; +import { + ssrfPolicyFromDangerouslyAllowPrivateNetwork, + type SsrFPolicy, +} from "../../runtime-api.js"; import type { MatrixClient } from "../sdk.js"; import { resolveValidatedMatrixHomeserverUrl } from "./config.js"; import { @@ -95,7 +98,8 @@ export async function createMatrixClient(params: { idbSnapshotPath: storagePaths?.idbSnapshotPath, cryptoDatabasePrefix, autoBootstrapCrypto: params.autoBootstrapCrypto, - ssrfPolicy: params.ssrfPolicy, + ssrfPolicy: + params.ssrfPolicy ?? ssrfPolicyFromDangerouslyAllowPrivateNetwork(params.allowPrivateNetwork), dispatcherPolicy: params.dispatcherPolicy, }); }