Hello!
I'm struggling to figure out a 'proper' way to secure the below file router. I don't want the user to be able to escape the 'public' directory. Sure I can sanitise the URL, but that would make the navigation more complicated. What would be the correct way to secure the below, please?
import { join as pathJoin } from "path";
import { createClient } from "redis";
const redis = createClient({
url: "redis://host.docker.internal:6379"
});
redis.connect();
Bun.serve({
async fetch(req, server) {
const licenceHash = req.headers.get("Authorization")?.split(" ")[1];
if (!licenceHash) return new Response("Not Authorized", { status: 401 });
const licence = await redis.hGetAll(`licence:${licenceHash}`);
if (!licence.key) return new Response("Forbidden", { status: 403 });
const requestURL = new URL(req.url);
const resourcePath = pathJoin('public', requestURL.pathname);
const resource = Bun.file(resourcePath);
const resourceExists = await resource.exists();
if (!resourceExists) return new Response("Not Found", { status: 404 });
return new Response(JSON.stringify(licence, null, 2));
}
});
I don't want the user to be able to navigate up into the host filesystem by using a URL such as "http://localhost:3000/../../../"