- 安全响应头中间件:nosniff / X-Frame-Options DENY / Referrer-Policy / CSP / Permissions-Policy,最外层覆盖所有响应 - loopback CORS 由 mirror_request 改为 loopback origin 白名单(原实现会回显任意 Origin,允许恶意网页跨域读取本地网关) - 新增 gateway.allowed_origins 配置:非 loopback 部署可收紧 CORS,未配置时保持 permissive 并打 warn - loopback 免认证模式强制 Host 头为 loopback,阻断 DNS rebinding - loopback 免认证模式 WS Origin 必须为 loopback 来源,防跨站 WebSocket 劫持(CSWSH) - WS 消息/帧大小显式上限 80MiB/16MiB(顺带修复 50MB 附件 base64 超 tungstenite 默认 64MB 上限的问题) - HTTP 请求体显式限制 2MB(DefaultBodyLimit) - 前端 HTTPS 页面自动使用 wss://,避免混合内容拦截 WebSocket - 新增 10 个安全相关单元测试(host/origin loopback 判定、WS Origin 校验)
34 lines
1.3 KiB
TypeScript
34 lines
1.3 KiB
TypeScript
// 网关连接设置的 localStorage 工具函数
|
||
// 原 SettingsModal 组件已删除(功能由 ConfigPage 的 Connection Tab 承担),
|
||
// 仅保留 App.tsx 使用的 getGatewaySettings / buildWsUrl / GatewaySettings 工具函数
|
||
|
||
import { getAuthToken } from '../../api/client';
|
||
|
||
export interface GatewaySettings {
|
||
host: string;
|
||
port: number;
|
||
}
|
||
|
||
const DEFAULT_HOST = '127.0.0.1';
|
||
const DEFAULT_PORT = 19876;
|
||
|
||
export function getGatewaySettings(): GatewaySettings {
|
||
try {
|
||
const host = localStorage.getItem('picobot-gateway-host') || DEFAULT_HOST;
|
||
const portStr = localStorage.getItem('picobot-gateway-port');
|
||
const port = portStr ? parseInt(portStr, 10) : DEFAULT_PORT;
|
||
return { host, port: isNaN(port) ? DEFAULT_PORT : port };
|
||
} catch {
|
||
return { host: DEFAULT_HOST, port: DEFAULT_PORT };
|
||
}
|
||
}
|
||
|
||
export function buildWsUrl(settings: GatewaySettings): string {
|
||
// HTTPS 页面下浏览器禁止混合内容(ws://),需使用 wss://
|
||
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
||
const base = `${protocol}://${settings.host}:${settings.port}/ws`;
|
||
// 远程访问时需要携带认证 token(浏览器原生 WebSocket 不支持自定义 header)
|
||
const token = getAuthToken();
|
||
return token ? `${base}?token=${encodeURIComponent(token)}` : base;
|
||
}
|