fix(security): bind temporary media server to loopback

This commit is contained in:
MaxMiksa 2026-01-28 20:54:05 -05:00
parent f4004054ab
commit b1c88dd7d7
3 changed files with 11 additions and 3 deletions

View File

@ -42,9 +42,9 @@ export async function ensureMediaHosted(
}
if (needsServerStart && opts.startServer) {
if (!mediaServer) {
mediaServer = await startMediaServer(port, TTL_MS, runtime);
mediaServer = await startMediaServer(port, TTL_MS, undefined, runtime);
logInfo(
`🦞 Started temporary media host on http://localhost:${port}/media/:id (TTL ${TTL_MS / 1000}s)`,
`🦞 Started temporary media host on http://127.0.0.1:${port}/media/:id (TTL ${TTL_MS / 1000}s)`,
runtime,
);
mediaServer.unref?.();

View File

@ -54,6 +54,13 @@ describe("media server", () => {
await new Promise((r) => server.close(r));
});
it("binds to loopback by default", async () => {
const server = await startMediaServer(0, 5_000);
const addr = server.address() as AddressInfo;
expect(["127.0.0.1", "::1"]).toContain(addr.address);
await new Promise((r) => server.close(r));
});
it("expires old media", async () => {
const file = path.join(MEDIA_DIR, "old");
await fs.writeFile(file, "stale");

View File

@ -83,12 +83,13 @@ export function attachMediaRoutes(
export async function startMediaServer(
port: number,
ttlMs = DEFAULT_TTL_MS,
host = "127.0.0.1",
runtime: RuntimeEnv = defaultRuntime,
): Promise<Server> {
const app = express();
attachMediaRoutes(app, ttlMs, runtime);
return await new Promise((resolve, reject) => {
const server = app.listen(port);
const server = app.listen(port, host);
server.once("listening", () => resolve(server));
server.once("error", (err) => {
runtime.error(danger(`Media server failed: ${String(err)}`));