fix(auth): WS Origin host check + Login next-param open-redirect guard

This commit is contained in:
saopig1 committed 2026-05-27 14:02:33 +08:00
1 parent e148c1556e
commit a8b056d2aa
2 files changed
+17 -1

No files matched your search

+15
View File
@@ -123,6 +123,21 @@ export function createWebServer(options: WebServerOptions): WebServer {
socket.destroy(); socket.destroy();
return; return;
} }
const reqHost = req.headers.host;
const originHeader = req.headers.origin;
if (originHeader) {
let originHost: string | null = null;
try {
originHost = new URL(originHeader).host;
} catch {
// fall through; treat as missing/invalid origin
}
if (!originHost || originHost !== reqHost) {
socket.write("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
socket.destroy();
return;
}
}
const result = validateSessionFromHeaders(req.headers.cookie as string | undefined, sessions); const result = validateSessionFromHeaders(req.headers.cookie as string | undefined, sessions);
if (!result) { if (!result) {
socket.write("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n"); socket.write("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
+2 -1
View File
@@ -34,7 +34,8 @@ async function submit() {
loading.value = true; loading.value = true;
try { try {
await session.login(username.value, password.value); await session.login(username.value, password.value);
const next = typeof route.query.next === 'string' ? route.query.next : '/'; const rawNext = typeof route.query.next === 'string' ? route.query.next : '/';
const next = rawNext.startsWith('/') && !rawNext.startsWith('//') ? rawNext : '/';
router.replace(next); router.replace(next);
} catch (e) { } catch (e) {
error.value = (e as Error).message; error.value = (e as Error).message;