Critical Securities (5) fixes
This commit is contained in:
+26
-6
@@ -6,7 +6,7 @@ import { verify } from './servers/jwt';
|
||||
import { isTokenBlacklisted } from 'officerdb';
|
||||
import { terminalWebsocket, initTerminalSidecars } from './servers/api/terminal/websocket';
|
||||
import { piWebsocket } from './servers/api/pi/websocket';
|
||||
import { findEntryBySlug, touchEntry } from './servers/api/dev-server/router';
|
||||
import { findEntryByProxyId, touchEntry } from './servers/api/dev-server/router';
|
||||
import officerWeb from './apps/officer-web/index.html';
|
||||
|
||||
const { PORT = '5000' } = process.env;
|
||||
@@ -26,6 +26,7 @@ type WSData = {
|
||||
devServerPort?: number;
|
||||
devServerSlug?: string;
|
||||
wsProxyPath?: string;
|
||||
wsToken?: string;
|
||||
};
|
||||
|
||||
const handlers: Record<string, any> = {
|
||||
@@ -38,8 +39,23 @@ type UpstreamState = { ws: WebSocket; queue: (string | Buffer)[]; ready: boolean
|
||||
const devServerUpstreams = new Map<ServerWebSocket<WSData>, UpstreamState>();
|
||||
|
||||
const devServerWebsocket = {
|
||||
open(ws: ServerWebSocket<WSData>) {
|
||||
const { devServerPort, wsProxyPath } = ws.data;
|
||||
async open(ws: ServerWebSocket<WSData>) {
|
||||
const { devServerPort, wsProxyPath, wsToken } = ws.data;
|
||||
|
||||
// Validate JWT (deferred from upgrade which must be synchronous in Bun)
|
||||
if (!wsToken) {
|
||||
ws.close(4001, 'Unauthorized');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const payload = await verify(wsToken);
|
||||
if (!payload) { ws.close(4001, 'Unauthorized'); return; }
|
||||
if (payload.jti && isTokenBlacklisted(payload.jti)) { ws.close(4001, 'Unauthorized'); return; }
|
||||
} catch {
|
||||
ws.close(4001, 'Unauthorized');
|
||||
return;
|
||||
}
|
||||
|
||||
const upstream = new WebSocket(`ws://localhost:${devServerPort}${wsProxyPath}`);
|
||||
const state: UpstreamState = { ws: upstream, queue: [], ready: false };
|
||||
devServerUpstreams.set(ws, state);
|
||||
@@ -116,10 +132,13 @@ function upgradeDevServerWs(req: Request, server: any) {
|
||||
const match = url.pathname.match(/^\/api\/dev-server-proxy\/([^/]+)(\/.*)?$/);
|
||||
if (!match) return new Response('Not found', { status: 404 });
|
||||
|
||||
const slug = match[1]!;
|
||||
const entry = findEntryBySlug(slug);
|
||||
const proxyId = match[1]!;
|
||||
const entry = findEntryByProxyId(proxyId);
|
||||
if (!entry) return new Response('No dev server running', { status: 404 });
|
||||
|
||||
const wsToken = url.searchParams.get('token');
|
||||
if (!wsToken) return new Response('Unauthorized', { status: 401 });
|
||||
|
||||
touchEntry(entry);
|
||||
|
||||
const wsProxyPath = match[2] || '/';
|
||||
@@ -131,8 +150,9 @@ function upgradeDevServerWs(req: Request, server: any) {
|
||||
provider: 'dev-server' as const,
|
||||
sandboxed: false,
|
||||
devServerPort: entry.port,
|
||||
devServerSlug: slug,
|
||||
devServerSlug: proxyId,
|
||||
wsProxyPath,
|
||||
wsToken,
|
||||
},
|
||||
});
|
||||
if (!ok) return new Response('Upgrade failed', { status: 500 });
|
||||
|
||||
Reference in New Issue
Block a user