fix potential sandbox escape via custom vencordDir

This commit is contained in:
Vendicated
2024-07-04 18:40:04 +02:00
parent ec3d83f7ca
commit 1f12d270ec
9 changed files with 84 additions and 20 deletions

View File

@@ -37,7 +37,8 @@ if (existsSync(LEGACY_DATA_DIR)) {
console.error("Migration failed", e);
}
}
app.setPath("sessionData", join(DATA_DIR, "sessionData"));
const SESSION_DATA_DIR = join(DATA_DIR, "sessionData");
app.setPath("sessionData", SESSION_DATA_DIR);
export const VENCORD_SETTINGS_DIR = join(DATA_DIR, "settings");
export const VENCORD_QUICKCSS_FILE = join(VENCORD_SETTINGS_DIR, "quickCss.css");
@@ -47,7 +48,8 @@ export const VENCORD_THEMES_DIR = join(DATA_DIR, "themes");
// needs to be inline require because of circular dependency
// as otherwise "DATA_DIR" (which is used by ./settings) will be uninitialised
export const VENCORD_FILES_DIR =
(require("./settings") as typeof import("./settings")).Settings.store.vencordDir || join(DATA_DIR, "vencordDist");
(require("./settings") as typeof import("./settings")).State.store.vencordDir ||
join(SESSION_DATA_DIR, "vencordFiles");
export const USER_AGENT = `Vesktop/${app.getVersion()} (https://github.com/Vencord/Vesktop)`;

View File

@@ -19,7 +19,7 @@ import { setBadgeCount } from "./appBadge";
import { autoStart } from "./autoStart";
import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants";
import { mainWin } from "./mainWindow";
import { Settings } from "./settings";
import { Settings, State } from "./settings";
import { handle, handleSync } from "./utils/ipcWrappers";
import { PopoutWindows } from "./utils/popout";
import { isDeckGameMode, showGamePage } from "./utils/steamOS";
@@ -105,7 +105,15 @@ handle(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, (e, word: string) => {
e.sender.session.addWordToSpellCheckerDictionary(word);
});
handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
handleSync(IpcEvents.GET_VENCORD_DIR, e => (e.returnValue = State.store.vencordDir));
handle(IpcEvents.SELECT_VENCORD_DIR, async (_e, value?: null) => {
console.log(value);
if (value === null) {
delete State.store.vencordDir;
return "ok";
}
const res = await dialog.showOpenDialog(mainWin!, {
properties: ["openDirectory"]
});
@@ -114,7 +122,9 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
const dir = res.filePaths[0];
if (!isValidVencordInstall(dir)) return "invalid";
return dir;
State.store.vencordDir = dir;
return "ok";
});
handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));

View File

@@ -4,7 +4,8 @@
* Copyright (c) 2023 Vendicated and Vencord contributors
*/
import { existsSync, mkdirSync } from "fs";
import { mkdirSync } from "fs";
import { access, constants as FsConstants } from "fs/promises";
import { join } from "path";
import { USER_AGENT, VENCORD_FILES_DIR } from "../constants";
@@ -56,12 +57,18 @@ export async function downloadVencordFiles() {
);
}
export function isValidVencordInstall(dir: string) {
return FILES_TO_DOWNLOAD.every(f => existsSync(join(dir, f)));
const existsAsync = (path: string) =>
access(path, FsConstants.F_OK)
.then(() => true)
.catch(() => false);
export async function isValidVencordInstall(dir: string) {
return Promise.all(FILES_TO_DOWNLOAD.map(f => existsAsync(join(dir, f)))).then(arr => !arr.includes(false));
}
export async function ensureVencordFiles() {
if (isValidVencordInstall(VENCORD_FILES_DIR)) return;
if (await isValidVencordInstall(VENCORD_FILES_DIR)) return;
mkdirSync(VENCORD_FILES_DIR, { recursive: true });
await downloadVencordFiles();