mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-20 21:23:23 +00:00
fix: keep tui out of browser origin checks
This commit is contained in:
@@ -224,6 +224,32 @@ describe("gateway auth browser hardening", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("rejects browser-origin connects that claim to be tui clients", async () => {
|
||||
testState.gatewayAuth = { mode: "token", token: "secret" };
|
||||
await withGatewayServer(async ({ port }) => {
|
||||
const ws = await openWs(port, { origin: "https://attacker.example" });
|
||||
try {
|
||||
const res = await connectReq(ws, {
|
||||
token: "secret",
|
||||
client: {
|
||||
id: GATEWAY_CLIENT_NAMES.TUI,
|
||||
version: "1.0.0",
|
||||
platform: "darwin",
|
||||
mode: GATEWAY_CLIENT_MODES.UI,
|
||||
},
|
||||
device: null,
|
||||
});
|
||||
expect(res.ok).toBe(false);
|
||||
expect(res.error?.message ?? "").toContain("origin not allowed");
|
||||
expect((res.error?.details as { code?: string } | undefined)?.code).toBe(
|
||||
ConnectErrorDetailCodes.CONTROL_UI_ORIGIN_NOT_ALLOWED,
|
||||
);
|
||||
} finally {
|
||||
ws.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("rate-limits browser-origin auth failures on loopback even when loopback exemption is enabled", async () => {
|
||||
testState.gatewayAuth = {
|
||||
mode: "token",
|
||||
|
||||
@@ -299,9 +299,7 @@ export function registerControlUiAndPairingSuite(): void {
|
||||
|
||||
test("allows localhost tui without device identity when insecure auth is enabled", async () => {
|
||||
testState.gatewayControlUi = { allowInsecureAuth: true };
|
||||
const { server, ws, prevToken } = await startServerWithClient("secret", {
|
||||
wsHeaders: { origin: "http://127.0.0.1" },
|
||||
});
|
||||
const { server, ws, prevToken } = await startServerWithClient("secret");
|
||||
await connectControlUiWithoutDeviceAndExpectOk({
|
||||
ws,
|
||||
token: "secret",
|
||||
|
||||
@@ -24,6 +24,7 @@ import { rawDataToString } from "../../../infra/ws.js";
|
||||
import type { createSubsystemLogger } from "../../../logging/subsystem.js";
|
||||
import { roleScopesAllow } from "../../../shared/operator-scope-compat.js";
|
||||
import {
|
||||
isBrowserOperatorUiClient,
|
||||
isGatewayCliClient,
|
||||
isOperatorUiClient,
|
||||
isWebchatClient,
|
||||
@@ -405,8 +406,9 @@ export function attachGatewayWsMessageHandler(params: {
|
||||
connectParams.scopes = scopes;
|
||||
|
||||
const isControlUi = isOperatorUiClient(connectParams.client);
|
||||
const isBrowserOperatorUi = isBrowserOperatorUiClient(connectParams.client);
|
||||
const isWebchat = isWebchatConnect(connectParams);
|
||||
if (enforceOriginCheckForAnyClient || isControlUi || isWebchat) {
|
||||
if (enforceOriginCheckForAnyClient || isBrowserOperatorUi || isWebchat) {
|
||||
const hostHeaderOriginFallbackEnabled =
|
||||
configSnapshot.gateway?.controlUi?.dangerouslyAllowHostHeaderOriginFallback === true;
|
||||
const originCheck = checkBrowserOrigin({
|
||||
|
||||
@@ -47,6 +47,11 @@ export function isOperatorUiClient(client?: GatewayClientInfoLike | null): boole
|
||||
return clientId === GATEWAY_CLIENT_NAMES.CONTROL_UI || clientId === GATEWAY_CLIENT_NAMES.TUI;
|
||||
}
|
||||
|
||||
export function isBrowserOperatorUiClient(client?: GatewayClientInfoLike | null): boolean {
|
||||
const clientId = normalizeGatewayClientName(client?.id);
|
||||
return clientId === GATEWAY_CLIENT_NAMES.CONTROL_UI;
|
||||
}
|
||||
|
||||
export function isInternalMessageChannel(raw?: string | null): raw is InternalMessageChannel {
|
||||
return normalizeMessageChannel(raw) === INTERNAL_MESSAGE_CHANNEL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user