mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
fix path validation bug
This commit is contained in:
@@ -263,8 +263,12 @@ router.post("/rename", async (req, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldResolved = resolveVaultPath(vaultRoot, req.body?.oldPath);
|
if (!req.body?.oldPath || !req.body?.newPath) {
|
||||||
const newResolved = resolveVaultPath(vaultRoot, req.body?.newPath);
|
return res.status(400).json({ error: "Missing oldPath or newPath" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldResolved = resolveVaultPath(vaultRoot, req.body.oldPath);
|
||||||
|
const newResolved = resolveVaultPath(vaultRoot, req.body.newPath);
|
||||||
|
|
||||||
if (!oldResolved || !newResolved) {
|
if (!oldResolved || !newResolved) {
|
||||||
return res.status(403).json({ error: "Invalid path" });
|
return res.status(403).json({ error: "Invalid path" });
|
||||||
@@ -288,8 +292,12 @@ router.post("/copyFile", async (req, res) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const srcResolved = resolveVaultPath(vaultRoot, req.body?.src);
|
if (!req.body?.src || !req.body?.dest) {
|
||||||
const destResolved = resolveVaultPath(vaultRoot, req.body?.dest);
|
return res.status(400).json({ error: "Missing src or dest" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const srcResolved = resolveVaultPath(vaultRoot, req.body.src);
|
||||||
|
const destResolved = resolveVaultPath(vaultRoot, req.body.dest);
|
||||||
|
|
||||||
if (!srcResolved || !destResolved) {
|
if (!srcResolved || !destResolved) {
|
||||||
return res.status(403).json({ error: "Invalid path" });
|
return res.status(403).json({ error: "Invalid path" });
|
||||||
|
|||||||
@@ -77,12 +77,12 @@ describe("resolveVaultPath", () => {
|
|||||||
expect(resolveVaultPath(root, "")).toBe(path.resolve(root));
|
expect(resolveVaultPath(root, "")).toBe(path.resolve(root));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("treats null input as vault root", () => {
|
it("returns null for null input", () => {
|
||||||
expect(resolveVaultPath(root, null)).toBe(path.resolve(root));
|
expect(resolveVaultPath(root, null)).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("treats undefined input as vault root", () => {
|
it("returns null for undefined input", () => {
|
||||||
expect(resolveVaultPath(root, undefined)).toBe(path.resolve(root));
|
expect(resolveVaultPath(root, undefined)).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("strips leading slashes", () => {
|
it("strips leading slashes", () => {
|
||||||
|
|||||||
@@ -46,8 +46,13 @@ function encodeContentDispositionFilename(filename) {
|
|||||||
|
|
||||||
// Resolve a client-provided path to an absolute path within a vault.
|
// Resolve a client-provided path to an absolute path within a vault.
|
||||||
// Strips leading slashes so paths from the client are always treated as relative to the vault root.
|
// Strips leading slashes so paths from the client are always treated as relative to the vault root.
|
||||||
|
// Rejects nullish input so missing-field bugs in callers don't silently target the vault root.
|
||||||
function resolveVaultPath(vaultRoot, relativePath) {
|
function resolveVaultPath(vaultRoot, relativePath) {
|
||||||
const cleaned = (relativePath || "").replace(/^\/+/, "");
|
if (relativePath === null || relativePath === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleaned = relativePath.replace(/^\/+/, "");
|
||||||
const resolved = path.resolve(vaultRoot, cleaned);
|
const resolved = path.resolve(vaultRoot, cleaned);
|
||||||
|
|
||||||
const resolvedRoot = path.resolve(vaultRoot);
|
const resolvedRoot = path.resolve(vaultRoot);
|
||||||
|
|||||||
Reference in New Issue
Block a user