PicoBot/web/src/components/Settings/SettingsModal.tsx
oudecheng f2fc5e97ac feat(security): 部署安全加固(排除 token 项)
- 安全响应头中间件: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 校验)
2026-08-17 06:47:35 +08:00

34 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 网关连接设置的 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;
}