mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-21 22:52:19 +03:00
fix(security): require auth for db-backups export/import under requireLogin=false
/api/db-backups/export and /import sat outside ALWAYS_PROTECTED_API_PATHS, so with requireLogin=false an anonymous caller could stream the full SQLite database (api_keys, provider credentials, OAuth tokens) or replace it wholesale. Adding /api/db-backups to the Tier-2 allowlist requires a credential for all three sibling routes, matching the trade-off /api/settings/database already makes. Reported by @ntdat812 via GHSA-mghq-58h3-qcqj.
This commit is contained in:
@@ -119,6 +119,11 @@ export const ALWAYS_PROTECTED_API_PATHS: ReadonlyArray<string> = [
|
||||
"/api/shutdown",
|
||||
"/api/providers/health-autopilot/actions",
|
||||
"/api/settings/database",
|
||||
// Full-database export/import: a credential dump and an irreversible replace.
|
||||
// Must stay authenticated even under requireLogin=false, for the same reason
|
||||
// /api/settings/database already does. isAlwaysProtectedPath matches on a path
|
||||
// boundary, so this covers export, exportAll and import. (GHSA-mghq-58h3-qcqj)
|
||||
"/api/db-backups",
|
||||
];
|
||||
|
||||
export function isLoopbackHost(hostHeader: string | null): boolean {
|
||||
|
||||
@@ -58,6 +58,15 @@ test("isAlwaysProtectedPath: /api/settings/database is always protected", () =>
|
||||
assert.equal(isAlwaysProtectedPath("/api/settings/database"), true);
|
||||
});
|
||||
|
||||
test("isAlwaysProtectedPath: /api/db-backups is always protected (GHSA-mghq-58h3-qcqj)", () => {
|
||||
// Full-database read/replace must require auth even when requireLogin=false —
|
||||
// the same Tier-2 trade-off /api/settings/database already makes. The single
|
||||
// prefix entry covers export, exportAll, import and future siblings.
|
||||
assert.equal(isAlwaysProtectedPath("/api/db-backups/export"), true);
|
||||
assert.equal(isAlwaysProtectedPath("/api/db-backups/exportAll"), true);
|
||||
assert.equal(isAlwaysProtectedPath("/api/db-backups/import"), true);
|
||||
});
|
||||
|
||||
test("isAlwaysProtectedPath: ordinary settings routes are not always protected", () => {
|
||||
assert.equal(isAlwaysProtectedPath("/api/settings"), false);
|
||||
assert.equal(isAlwaysProtectedPath("/api/settings/proxy"), false);
|
||||
|
||||
Reference in New Issue
Block a user