From a36d22ad63dc3fbfc9ba514e7f85a0092fdcd6c4 Mon Sep 17 00:00:00 2001 From: Rai Butera Date: Sat, 14 Mar 2026 11:53:33 +0000 Subject: [PATCH] fix(gateway): limit plugin route backend trust --- src/gateway/server/plugins-http.test.ts | 34 +++++++++++++++++++++++++ src/gateway/server/plugins-http.ts | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/gateway/server/plugins-http.test.ts b/src/gateway/server/plugins-http.test.ts index 1a4866d7d23..8c745ef8bfd 100644 --- a/src/gateway/server/plugins-http.test.ts +++ b/src/gateway/server/plugins-http.test.ts @@ -178,6 +178,40 @@ describe("createGatewayPluginRequestHandler", () => { expect(log.warn).toHaveBeenCalledWith(expect.stringContaining("missing scope: operator.admin")); }); + it("does not mark unauthenticated plugin routes as internal backend clients", async () => { + loadOpenClawPlugins.mockReset(); + handleGatewayRequest.mockReset(); + handleGatewayRequest.mockImplementation(async (opts: HandleGatewayRequestOptions) => { + opts.respond(true, { internal: opts.client?.isInternalBackendClient === true }); + }); + + const subagent = await createSubagentRuntime(); + const handler = createGatewayPluginRequestHandler({ + registry: createTestRegistry({ + httpRoutes: [ + createRoute({ + path: "/hook", + auth: "plugin", + handler: async (_req, _res) => { + await subagent.deleteSession({ sessionKey: "agent:main:subagent:child" }); + return true; + }, + }), + ], + }), + log: createPluginLog(), + }); + + const { res } = makeMockHttpResponse(); + const handled = await handler({ url: "/hook" } as IncomingMessage, res, undefined, { + gatewayAuthSatisfied: false, + }); + + expect(handled).toBe(true); + expect(handleGatewayRequest).toHaveBeenCalledTimes(1); + expect(handleGatewayRequest.mock.calls[0]?.[0]?.client?.isInternalBackendClient).toBe(false); + }); + it("returns false when no routes are registered", async () => { const log = createPluginLog(); const handler = createGatewayPluginRequestHandler({ diff --git a/src/gateway/server/plugins-http.ts b/src/gateway/server/plugins-http.ts index fc59127037e..c2210cac90c 100644 --- a/src/gateway/server/plugins-http.ts +++ b/src/gateway/server/plugins-http.ts @@ -49,7 +49,7 @@ function createPluginRouteRuntimeClient(params: { role: "operator", scopes, }, - isInternalBackendClient: true, + isInternalBackendClient: params.requiresGatewayAuth && params.gatewayAuthSatisfied !== false, }; }