mirror of
https://github.com/MasterAcnolo/Freedom-Loader.git
synced 2026-07-29 18:25:47 +02:00
Fix: Undo Path Validation for coming back on a classic one
This commit is contained in:
24
main.js
24
main.js
@@ -143,23 +143,23 @@ function validateDownloadPath(userPath) {
|
|||||||
|
|
||||||
// IPC
|
// IPC
|
||||||
ipcMain.handle("select-download-folder", async () => {
|
ipcMain.handle("select-download-folder", async () => {
|
||||||
try {
|
const result = await dialog.showOpenDialog({ properties: ["openDirectory"] });
|
||||||
const result = await dialog.showOpenDialog({ properties: ["openDirectory"] });
|
if (result.canceled) {
|
||||||
if (result.canceled) {
|
logger.info("Folder selection cancelled by user");
|
||||||
logger.info("Folder selection cancelled by user");
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
if (result.filePaths.length > 0) {
|
||||||
if (result.filePaths.length > 0) {
|
const selectedPath = result.filePaths[0];
|
||||||
const selectedPath = result.filePaths[0];
|
try {
|
||||||
const validatedPath = validateDownloadPath(selectedPath);
|
const validatedPath = validateDownloadPath(selectedPath);
|
||||||
logger.info(`Folder selected and validated: ${validatedPath}`);
|
logger.info(`Folder selected and validated: ${validatedPath}`);
|
||||||
return validatedPath;
|
return validatedPath;
|
||||||
|
} catch (err) {
|
||||||
|
logger.warn(`Unsafe or invalid folder rejected: ${err.message}`);
|
||||||
|
throw err; // Propagate error to UI
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
} catch (err) {
|
|
||||||
logger.warn(`Unsafe or invalid folder rejected: ${err.message}`);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle("validate-download-path", (event, userPath) => {
|
ipcMain.handle("validate-download-path", (event, userPath) => {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ window.addEventListener("DOMContentLoaded", async () => {
|
|||||||
|
|
||||||
await applyPathFromBack(validatedPath);
|
await applyPathFromBack(validatedPath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert("Folder not allowed.");
|
alert("This folder is not allowed. Only specific folders (Users, Downloads, Documents) are authorized for downloads.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,35 +12,10 @@ function isValidUrl(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isSafePath(folder) {
|
function isSafePath(folder) {
|
||||||
if (!folder || typeof folder !== "string") return false;
|
if (!folder || folder.length < 3) return false;
|
||||||
|
const unsafe = ["System32", "\\Windows"];
|
||||||
try {
|
const resolved = path.resolve(folder);
|
||||||
// Normalize path and resolve symlinks
|
return !unsafe.some(u => resolved.includes(u));
|
||||||
const resolved = path.resolve(folder).toLowerCase().replace(/\//g, "\\");
|
|
||||||
|
|
||||||
// Block Windows system directories (on any drive)
|
|
||||||
const unsafePaths = [
|
|
||||||
"\\windows\\",
|
|
||||||
"\\system32\\",
|
|
||||||
"\\program files\\",
|
|
||||||
"\\program files (x86)\\",
|
|
||||||
"\\programdata\\",
|
|
||||||
"\\$recycle.bin\\",
|
|
||||||
"\\system volume information\\"
|
|
||||||
];
|
|
||||||
|
|
||||||
// Check if path contains any unsafe directory
|
|
||||||
if (unsafePaths.some(unsafe => resolved.includes(unsafe))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow all drives (C:, D:, E:, etc.) but block system folders
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
// In case of path resolution error
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { isValidUrl, isSafePath };
|
module.exports = { isValidUrl, isSafePath };
|
||||||
|
|||||||
@@ -3,23 +3,33 @@ const { userYtDlp, defaultDownloadFolder } = require("../helpers/path");
|
|||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const { logger } = require("../logger");
|
const { logger } = require("../logger");
|
||||||
const { buildYtDlpArgs } = require("../helpers/buildArgs");
|
const { buildYtDlpArgs } = require("../helpers/buildArgs");
|
||||||
const notify = require("../helpers/notify")
|
const notify = require("../helpers/notify");
|
||||||
|
const path = require("path");
|
||||||
|
const { isSafePath } = require("../helpers/validation");
|
||||||
|
|
||||||
function fetchDownload(options, listeners, speedListeners) {
|
function fetchDownload(options, listeners, speedListeners) {
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const outputFolder = options.outputFolder || defaultDownloadFolder;
|
const outputFolder = options.outputFolder || defaultDownloadFolder;
|
||||||
|
|
||||||
|
// Normalize path and validate it's safe (within Users folder)
|
||||||
|
let safeOutputFolder = path.resolve(outputFolder);
|
||||||
|
|
||||||
|
if (!isSafePath(safeOutputFolder)) {
|
||||||
|
logger.warn(`Path not allowed, using default instead: ${safeOutputFolder}`);
|
||||||
|
safeOutputFolder = path.resolve(defaultDownloadFolder);
|
||||||
|
}
|
||||||
|
|
||||||
// Create download folder if it doesn't exist
|
// Create download folder if it doesn't exist
|
||||||
try {
|
try {
|
||||||
fs.mkdirSync(outputFolder, { recursive: true });
|
fs.mkdirSync(safeOutputFolder, { recursive: true });
|
||||||
logger.info(`Output folder ready: ${outputFolder}`);
|
logger.info(`Output folder ready: ${safeOutputFolder}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(`Failed to create output folder: ${err.message}`);
|
logger.error(`Failed to create output folder: ${err.message}`);
|
||||||
return reject(new Error(`Unable to create download folder: ${err.message}`));
|
return reject(new Error(`Unable to create download folder: ${err.message}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = buildYtDlpArgs({ ...options, outputFolder });
|
const args = buildYtDlpArgs({ ...options, outputFolder: safeOutputFolder });
|
||||||
logger.info(`[yt-dlp args] ${args.join(" ")}`);
|
logger.info(`[yt-dlp args] ${args.join(" ")}`);
|
||||||
|
|
||||||
const child = execFile(userYtDlp, args);
|
const child = execFile(userYtDlp, args);
|
||||||
@@ -28,7 +38,7 @@ function fetchDownload(options, listeners, speedListeners) {
|
|||||||
|
|
||||||
child.on("close", code => {
|
child.on("close", code => {
|
||||||
listeners.forEach(fn => fn("done"));
|
listeners.forEach(fn => fn("done"));
|
||||||
if (code === 0) resolve(outputFolder);
|
if (code === 0) resolve(safeOutputFolder);
|
||||||
else reject(new Error(`YT-DLP failed with code : ${code}`));
|
else reject(new Error(`YT-DLP failed with code : ${code}`));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user