Harden download integrity, extraction safety, and update security
This commit is contained in:
+72
-3
@@ -572,7 +572,7 @@ describe("settings storage", () => {
|
||||
expect(loaded.packageName).toBe("from-backup");
|
||||
});
|
||||
|
||||
it("sanitizes malformed persisted session structures", () => {
|
||||
it("sanitizes malformed persisted session structures", () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-store-"));
|
||||
tempDirs.push(dir);
|
||||
const paths = createStoragePaths(dir);
|
||||
@@ -609,8 +609,77 @@ describe("settings storage", () => {
|
||||
const loaded = loadSession(paths);
|
||||
expect(Object.keys(loaded.packages)).toEqual(["pkg-valid"]);
|
||||
expect(Object.keys(loaded.items)).toEqual(["item-valid"]);
|
||||
expect(loaded.packageOrder).toEqual(["pkg-valid"]);
|
||||
});
|
||||
expect(loaded.packageOrder).toEqual(["pkg-valid"]);
|
||||
});
|
||||
|
||||
it("drops unsafe session ids and target paths outside the package output directory", () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-store-"));
|
||||
tempDirs.push(dir);
|
||||
const paths = createStoragePaths(dir);
|
||||
const outputDir = path.join(dir, "downloads", "safe");
|
||||
const safeTargetPath = path.join(outputDir, "safe.bin");
|
||||
const outsideTargetPath = path.join(dir, "outside.bin");
|
||||
|
||||
fs.writeFileSync(paths.sessionFile, JSON.stringify({
|
||||
version: 2,
|
||||
packageOrder: ["pkg-safe", "../pkg-evil"],
|
||||
packages: {
|
||||
"pkg-safe": {
|
||||
id: "pkg-safe",
|
||||
name: "Safe Package",
|
||||
outputDir,
|
||||
extractDir: path.join(dir, "extract", "safe"),
|
||||
status: "queued",
|
||||
itemIds: ["item-safe", "item-outside", "../item-evil"],
|
||||
cancelled: false,
|
||||
enabled: true
|
||||
},
|
||||
"../pkg-evil": {
|
||||
id: "../pkg-evil",
|
||||
name: "Unsafe Package",
|
||||
outputDir,
|
||||
extractDir: path.join(dir, "extract", "unsafe"),
|
||||
status: "queued",
|
||||
itemIds: ["item-evil"],
|
||||
cancelled: false,
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
items: {
|
||||
"item-safe": {
|
||||
id: "item-safe",
|
||||
packageId: "pkg-safe",
|
||||
url: "https://example.com/safe",
|
||||
status: "queued",
|
||||
fileName: "safe.bin",
|
||||
targetPath: safeTargetPath
|
||||
},
|
||||
"item-outside": {
|
||||
id: "item-outside",
|
||||
packageId: "pkg-safe",
|
||||
url: "https://example.com/outside",
|
||||
status: "queued",
|
||||
fileName: "outside.bin",
|
||||
targetPath: outsideTargetPath
|
||||
},
|
||||
"../item-evil": {
|
||||
id: "../item-evil",
|
||||
packageId: "pkg-safe",
|
||||
url: "https://example.com/evil",
|
||||
status: "queued",
|
||||
fileName: "evil.bin",
|
||||
targetPath: safeTargetPath
|
||||
}
|
||||
}
|
||||
}), "utf8");
|
||||
|
||||
const loaded = loadSession(paths);
|
||||
expect(Object.keys(loaded.packages)).toEqual(["pkg-safe"]);
|
||||
expect(Object.keys(loaded.items).sort()).toEqual(["item-outside", "item-safe"]);
|
||||
expect(loaded.packageOrder).toEqual(["pkg-safe"]);
|
||||
expect(path.resolve(loaded.items["item-safe"]?.targetPath || "")).toBe(path.resolve(safeTargetPath));
|
||||
expect(loaded.items["item-outside"]?.targetPath).toBe("");
|
||||
});
|
||||
|
||||
it("captures async session save payload before later mutations", async () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-store-"));
|
||||
|
||||
Reference in New Issue
Block a user