fix: harden pi management verification
This commit is contained in:
@@ -29,6 +29,10 @@ async function run<T>(
|
||||
if (!managementAllowed(deps.config, principal.isAdmin)) {
|
||||
return reply.code(403).send({ code: "pi_management_forbidden", error: "Pi management is not permitted" });
|
||||
}
|
||||
if (deps.config.authMode === "none" && isManagementWrite(request.method)
|
||||
&& !sameOriginOrNonBrowser(request)) {
|
||||
return reply.code(403).send({ code: "pi_management_forbidden", error: "Pi management is not permitted" });
|
||||
}
|
||||
try {
|
||||
return await action();
|
||||
} catch (error) {
|
||||
@@ -44,3 +48,20 @@ function managementAllowed(config: AppConfig, isAdmin: boolean): boolean {
|
||||
return (config.authMode === "none" && !config.publicExposure)
|
||||
|| (config.authMode === "upstream" && isAdmin);
|
||||
}
|
||||
|
||||
function isManagementWrite(method: string): boolean {
|
||||
return method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE";
|
||||
}
|
||||
|
||||
function sameOriginOrNonBrowser(request: FastifyRequest): boolean {
|
||||
const origin = request.headers.origin;
|
||||
if (origin === undefined) return true;
|
||||
if (typeof origin !== "string" || typeof request.headers.host !== "string") return false;
|
||||
try {
|
||||
const supplied = new URL(origin);
|
||||
const expected = new URL(`${request.protocol}://${request.headers.host}`);
|
||||
return supplied.origin === expected.origin;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user