fix: harden application trust boundaries (#1317)

This commit is contained in:
ZacharyZcR
2026-08-24 07:55:17 +08:00
committed by GitHub
parent 30d72554fc
commit 2de9bb236b
31 changed files with 287 additions and 132 deletions
@@ -313,6 +313,7 @@ function ConsoleTerminalInner({
window.location.port === "");
let baseWsUrl: string;
let wsProtocols: string[] = [];
if (isDev) {
baseWsUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://localhost:30009`;
} else if (isElectronApp) {
@@ -331,12 +332,13 @@ function ConsoleTerminalInner({
toast.error(t("errors.remoteServerRequired"));
return;
}
baseWsUrl = resolvedUrl;
baseWsUrl = resolvedUrl.url;
wsProtocols = resolvedUrl.protocols;
} else {
baseWsUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}${getBasePath()}/docker/console/`;
}
const ws = new WebSocket(baseWsUrl);
const ws = new WebSocket(baseWsUrl, wsProtocols);
ws.onopen = () => {
const cols = terminal.cols || 80;
@@ -250,17 +250,18 @@ export const GuacamoleDisplay = forwardRef<
const origin = await resolveConnectionOrigin({
connectionType: connectionProtocol,
});
wsBase = await buildOriginWsUrl({
const target = await buildOriginWsUrl({
origin,
localPort: 30008,
localPath: "/guacamole/websocket/",
remotePath: "/guacamole/websocket/",
includeJwt: false,
});
if (!wsBase) {
if (!target) {
onError?.(t("errors.remoteServerRequired"));
return null;
}
wsBase = target.url;
} else {
wsBase = buildGuacamoleWebSocketBaseUrl({
isDev,
+6 -4
View File
@@ -10,6 +10,7 @@ import { FitAddon } from "@xterm/addon-fit";
import { useTranslation } from "react-i18next";
import { TriangleAlert } from "lucide-react";
import { isElectron } from "@/lib/electron";
import { websocketAuthProtocols } from "@/lib/ws-auth";
import { useTheme } from "@/components/theme-provider";
import { resolveTermixThemeColors } from "@/features/terminal/terminal-theme";
import { DEFAULT_TERMINAL_CONFIG, TERMINAL_FONTS } from "@/lib/terminal-themes";
@@ -102,9 +103,7 @@ export const Serial = forwardRef<SerialHandle, SerialProps>(function Serial(
const buildWsUrl = useCallback(() => {
// Serial is always local -- the device is physically attached to this
// desktop machine, so it never routes through a remote server.
const token = localStorage.getItem("jwt");
const base = "ws://127.0.0.1:30011";
return token ? `${base}?token=${encodeURIComponent(token)}` : base;
return "ws://127.0.0.1:30011";
}, []);
const disconnectWs = useCallback(() => {
@@ -124,7 +123,10 @@ export const Serial = forwardRef<SerialHandle, SerialProps>(function Serial(
return;
}
const ws = new WebSocket(url);
const ws = new WebSocket(
url,
websocketAuthProtocols(localStorage.getItem("jwt")),
);
wsRef.current = ws;
ws.onopen = () => {
+4 -2
View File
@@ -1201,6 +1201,7 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
window.location.port === "");
let baseWsUrl: string;
let wsProtocols: string[] = [];
if (isDev) {
baseWsUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://localhost:30002`;
@@ -1223,7 +1224,8 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
isConnectingRef.current = false;
return;
}
baseWsUrl = resolvedUrl;
baseWsUrl = resolvedUrl.url;
wsProtocols = resolvedUrl.protocols;
} else {
baseWsUrl = `${getBasePath()}/ssh/websocket/`;
}
@@ -1246,7 +1248,7 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
connectionTimeoutRef.current = null;
}
const ws = new WebSocket(baseWsUrl);
const ws = new WebSocket(baseWsUrl, wsProtocols);
webSocketRef.current = ws;
wasDisconnectedBySSH.current = false;
updateConnectionError(null);