Enable process sandboxing (#1206)
This commit is contained in:
+21
-31
@@ -18,17 +18,15 @@ import {
|
|||||||
session,
|
session,
|
||||||
shell
|
shell
|
||||||
} from "electron";
|
} from "electron";
|
||||||
import { mkdirSync, readFileSync, watch } from "fs";
|
import { readFileSync, watch } from "fs";
|
||||||
import { open, readFile } from "fs/promises";
|
import { readFile } from "fs/promises";
|
||||||
import { enableHardwareAcceleration } from "main";
|
import { enableHardwareAcceleration } from "main";
|
||||||
import { release } from "os";
|
import { release } from "os";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { debounce } from "shared/utils/debounce";
|
|
||||||
|
|
||||||
import { IpcEvents } from "../shared/IpcEvents";
|
import { IpcEvents } from "../shared/IpcEvents";
|
||||||
import { setBadgeCount } from "./appBadge";
|
import { setBadgeCount } from "./appBadge";
|
||||||
import { autoStart } from "./autoStart";
|
import { autoStart } from "./autoStart";
|
||||||
import { VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants";
|
|
||||||
import { mainWin } from "./mainWindow";
|
import { mainWin } from "./mainWindow";
|
||||||
import { Settings, State } from "./settings";
|
import { Settings, State } from "./settings";
|
||||||
import { handle, handleSync } from "./utils/ipcWrappers";
|
import { handle, handleSync } from "./utils/ipcWrappers";
|
||||||
@@ -37,13 +35,29 @@ import { isDeckGameMode, showGamePage } from "./utils/steamOS";
|
|||||||
import { isValidVencordInstall } from "./utils/vencordLoader";
|
import { isValidVencordInstall } from "./utils/vencordLoader";
|
||||||
import { VENCORD_FILES_DIR } from "./vencordFilesDir";
|
import { VENCORD_FILES_DIR } from "./vencordFilesDir";
|
||||||
|
|
||||||
handleSync(IpcEvents.GET_VENCORD_PRELOAD_FILE, () => join(VENCORD_FILES_DIR, "vencordDesktopPreload.js"));
|
handleSync(IpcEvents.DEPRECATED_GET_VENCORD_PRELOAD_SCRIPT_PATH, () =>
|
||||||
|
join(VENCORD_FILES_DIR, "vencordDesktopPreload.js")
|
||||||
|
);
|
||||||
|
handleSync(IpcEvents.GET_VENCORD_PRELOAD_SCRIPT, () =>
|
||||||
|
readFileSync(join(VENCORD_FILES_DIR, "vencordDesktopPreload.js"), "utf-8")
|
||||||
|
);
|
||||||
handleSync(IpcEvents.GET_VENCORD_RENDERER_SCRIPT, () =>
|
handleSync(IpcEvents.GET_VENCORD_RENDERER_SCRIPT, () =>
|
||||||
readFileSync(join(VENCORD_FILES_DIR, "vencordDesktopRenderer.js"), "utf-8")
|
readFileSync(join(VENCORD_FILES_DIR, "vencordDesktopRenderer.js"), "utf-8")
|
||||||
);
|
);
|
||||||
|
|
||||||
handleSync(IpcEvents.GET_RENDERER_SCRIPT, () => readFileSync(join(__dirname, "renderer.js"), "utf-8"));
|
const VESKTOP_RENDERER_JS_PATH = join(__dirname, "renderer.js");
|
||||||
handleSync(IpcEvents.GET_RENDERER_CSS_FILE, () => join(__dirname, "renderer.css"));
|
const VESKTOP_RENDERER_CSS_PATH = join(__dirname, "renderer.css");
|
||||||
|
handleSync(IpcEvents.GET_VESKTOP_RENDERER_SCRIPT, () => readFileSync(VESKTOP_RENDERER_JS_PATH, "utf-8"));
|
||||||
|
handle(IpcEvents.GET_VESKTOP_RENDERER_CSS, () => readFile(VESKTOP_RENDERER_CSS_PATH, "utf-8"));
|
||||||
|
|
||||||
|
if (IS_DEV) {
|
||||||
|
watch(VESKTOP_RENDERER_CSS_PATH, { persistent: false }, async () => {
|
||||||
|
mainWin?.webContents.postMessage(
|
||||||
|
IpcEvents.VESKTOP_RENDERER_CSS_UPDATE,
|
||||||
|
await readFile(VESKTOP_RENDERER_CSS_PATH, "utf-8")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
handleSync(IpcEvents.GET_SETTINGS, () => Settings.plain);
|
handleSync(IpcEvents.GET_SETTINGS, () => Settings.plain);
|
||||||
handleSync(IpcEvents.GET_VERSION, () => app.getVersion());
|
handleSync(IpcEvents.GET_VERSION, () => app.getVersion());
|
||||||
@@ -164,27 +178,3 @@ function openDebugPage(page: string) {
|
|||||||
|
|
||||||
handle(IpcEvents.DEBUG_LAUNCH_GPU, () => openDebugPage("chrome://gpu"));
|
handle(IpcEvents.DEBUG_LAUNCH_GPU, () => openDebugPage("chrome://gpu"));
|
||||||
handle(IpcEvents.DEBUG_LAUNCH_WEBRTC_INTERNALS, () => openDebugPage("chrome://webrtc-internals"));
|
handle(IpcEvents.DEBUG_LAUNCH_WEBRTC_INTERNALS, () => openDebugPage("chrome://webrtc-internals"));
|
||||||
|
|
||||||
function readCss() {
|
|
||||||
return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => "");
|
|
||||||
}
|
|
||||||
|
|
||||||
open(VENCORD_QUICKCSS_FILE, "a+").then(fd => {
|
|
||||||
fd.close();
|
|
||||||
watch(
|
|
||||||
VENCORD_QUICKCSS_FILE,
|
|
||||||
{ persistent: false },
|
|
||||||
debounce(async () => {
|
|
||||||
mainWin?.webContents.postMessage("VencordQuickCssUpdate", await readCss());
|
|
||||||
}, 50)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
mkdirSync(VENCORD_THEMES_DIR, { recursive: true });
|
|
||||||
watch(
|
|
||||||
VENCORD_THEMES_DIR,
|
|
||||||
{ persistent: false },
|
|
||||||
debounce(() => {
|
|
||||||
mainWin?.webContents.postMessage("VencordThemeUpdate", void 0);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import { destroyTray, initTray } from "./tray";
|
|||||||
import { clearData } from "./utils/clearData";
|
import { clearData } from "./utils/clearData";
|
||||||
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
||||||
import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS";
|
import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS";
|
||||||
import { downloadVencordFiles, ensureVencordFiles } from "./utils/vencordLoader";
|
import { downloadVencordFiles, ensureVencordFiles, vencordSupportsSandboxing } from "./utils/vencordLoader";
|
||||||
import { VENCORD_FILES_DIR } from "./vencordFilesDir";
|
import { VENCORD_FILES_DIR } from "./vencordFilesDir";
|
||||||
|
|
||||||
let isQuitting = false;
|
let isQuitting = false;
|
||||||
@@ -323,7 +323,7 @@ function buildBrowserWindowOptions(): BrowserWindowConstructorOptions {
|
|||||||
backgroundColor,
|
backgroundColor,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
sandbox: false, // TODO
|
sandbox: vencordSupportsSandboxing(),
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
devTools: true,
|
devTools: true,
|
||||||
preload: join(__dirname, "preload.js"),
|
preload: join(__dirname, "preload.js"),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { mkdirSync } from "fs";
|
import { mkdirSync, readFileSync } from "fs";
|
||||||
import { access, constants as FsConstants, writeFile } from "fs/promises";
|
import { access, constants as FsConstants, writeFile } from "fs/promises";
|
||||||
import { VENCORD_FILES_DIR } from "main/vencordFilesDir";
|
import { VENCORD_FILES_DIR } from "main/vencordFilesDir";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
@@ -75,3 +75,16 @@ export async function ensureVencordFiles() {
|
|||||||
|
|
||||||
await Promise.all([downloadVencordFiles(), writeFile(join(VENCORD_FILES_DIR, "package.json"), "{}")]);
|
await Promise.all([downloadVencordFiles(), writeFile(join(VENCORD_FILES_DIR, "package.json"), "{}")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this once enough time has passed
|
||||||
|
export function vencordSupportsSandboxing() {
|
||||||
|
const supports = readFileSync(join(VENCORD_FILES_DIR, "vencordDesktopMain.js"), "utf-8").includes(
|
||||||
|
"VencordGetRendererCss"
|
||||||
|
);
|
||||||
|
if (!supports) {
|
||||||
|
console.warn(
|
||||||
|
"⚠️ [VencordLoader] Vencord version is outdated and does not support sandboxing. Please update Vencord to the latest version."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return supports;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Node } from "@vencord/venmic";
|
import type { Node } from "@vencord/venmic";
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron/renderer";
|
||||||
import { IpcMessage, IpcResponse } from "main/ipcCommands";
|
import type { IpcMessage, IpcResponse } from "main/ipcCommands";
|
||||||
import type { Settings } from "shared/settings";
|
import type { Settings } from "shared/settings";
|
||||||
|
|
||||||
import { IpcEvents } from "../shared/IpcEvents";
|
import { IpcEvents } from "../shared/IpcEvents";
|
||||||
@@ -34,7 +34,14 @@ export const VesktopNative = {
|
|||||||
supportsWindowsTransparency: () => sendSync<boolean>(IpcEvents.SUPPORTS_WINDOWS_TRANSPARENCY),
|
supportsWindowsTransparency: () => sendSync<boolean>(IpcEvents.SUPPORTS_WINDOWS_TRANSPARENCY),
|
||||||
getEnableHardwareAcceleration: () => sendSync<boolean>(IpcEvents.GET_ENABLE_HARDWARE_ACCELERATION),
|
getEnableHardwareAcceleration: () => sendSync<boolean>(IpcEvents.GET_ENABLE_HARDWARE_ACCELERATION),
|
||||||
isOutdated: () => invoke<boolean>(IpcEvents.UPDATER_IS_OUTDATED),
|
isOutdated: () => invoke<boolean>(IpcEvents.UPDATER_IS_OUTDATED),
|
||||||
openUpdater: () => invoke<void>(IpcEvents.UPDATER_OPEN)
|
openUpdater: () => invoke<void>(IpcEvents.UPDATER_OPEN),
|
||||||
|
// used by vencord
|
||||||
|
getRendererCss: () => invoke<string>(IpcEvents.GET_VESKTOP_RENDERER_CSS),
|
||||||
|
onRendererCssUpdate: (cb: (newCss: string) => void) => {
|
||||||
|
if (!IS_DEV) return;
|
||||||
|
|
||||||
|
ipcRenderer.on(IpcEvents.VESKTOP_RENDERER_CSS_UPDATE, (_e, newCss: string) => cb(newCss));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
autostart: {
|
autostart: {
|
||||||
isEnabled: () => sendSync<boolean>(IpcEvents.AUTOSTART_ENABLED),
|
isEnabled: () => sendSync<boolean>(IpcEvents.AUTOSTART_ENABLED),
|
||||||
|
|||||||
+18
-28
@@ -4,39 +4,29 @@
|
|||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { contextBridge, ipcRenderer, webFrame } from "electron";
|
import { contextBridge, ipcRenderer, webFrame } from "electron/renderer";
|
||||||
import { readFileSync, watch } from "fs";
|
|
||||||
|
|
||||||
import { IpcEvents } from "../shared/IpcEvents";
|
import { IpcEvents } from "../shared/IpcEvents";
|
||||||
import { VesktopNative } from "./VesktopNative";
|
import { VesktopNative } from "./VesktopNative";
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld("VesktopNative", VesktopNative);
|
contextBridge.exposeInMainWorld("VesktopNative", VesktopNative);
|
||||||
|
|
||||||
require(ipcRenderer.sendSync(IpcEvents.GET_VENCORD_PRELOAD_FILE));
|
// TODO: remove this legacy workaround once some time has passed
|
||||||
|
const isSandboxed = typeof __dirname === "undefined";
|
||||||
|
if (isSandboxed) {
|
||||||
|
// While sandboxed, Electron "polyfills" these APIs as local variables.
|
||||||
|
// We have to pass them as arguments as they are not global
|
||||||
|
Function(
|
||||||
|
"require",
|
||||||
|
"Buffer",
|
||||||
|
"process",
|
||||||
|
"clearImmediate",
|
||||||
|
"setImmediate",
|
||||||
|
ipcRenderer.sendSync(IpcEvents.GET_VENCORD_PRELOAD_SCRIPT)
|
||||||
|
)(require, Buffer, process, clearImmediate, setImmediate);
|
||||||
|
} else {
|
||||||
|
require(ipcRenderer.sendSync(IpcEvents.DEPRECATED_GET_VENCORD_PRELOAD_SCRIPT_PATH));
|
||||||
|
}
|
||||||
|
|
||||||
webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_VENCORD_RENDERER_SCRIPT));
|
webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_VENCORD_RENDERER_SCRIPT));
|
||||||
webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_RENDERER_SCRIPT));
|
webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_VESKTOP_RENDERER_SCRIPT));
|
||||||
|
|
||||||
// #region css
|
|
||||||
const rendererCss = ipcRenderer.sendSync(IpcEvents.GET_RENDERER_CSS_FILE);
|
|
||||||
|
|
||||||
const style = document.createElement("style");
|
|
||||||
style.id = "vcd-css-core";
|
|
||||||
style.textContent = readFileSync(rendererCss, "utf-8");
|
|
||||||
|
|
||||||
if (document.readyState === "complete") {
|
|
||||||
document.documentElement.appendChild(style);
|
|
||||||
} else {
|
|
||||||
document.addEventListener("DOMContentLoaded", () => document.documentElement.appendChild(style), {
|
|
||||||
once: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_DEV) {
|
|
||||||
// persistent means keep process running if watcher is the only thing still running
|
|
||||||
// which we obviously don't want
|
|
||||||
watch(rendererCss, { persistent: false }, () => {
|
|
||||||
document.getElementById("vcd-css-core")!.textContent = readFileSync(rendererCss, "utf-8");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// #endregion
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { contextBridge, ipcRenderer } from "electron";
|
import { contextBridge, ipcRenderer } from "electron/renderer";
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld("VesktopSplashNative", {
|
contextBridge.exposeInMainWorld("VesktopSplashNative", {
|
||||||
onUpdateMessage(callback: (message: string) => void) {
|
onUpdateMessage(callback: (message: string) => void) {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron/renderer";
|
||||||
import { IpcEvents, UpdaterIpcEvents } from "shared/IpcEvents";
|
import type { IpcEvents, UpdaterIpcEvents } from "shared/IpcEvents";
|
||||||
|
|
||||||
export function invoke<T = any>(event: IpcEvents | UpdaterIpcEvents, ...args: any[]) {
|
export function invoke<T = any>(event: IpcEvents | UpdaterIpcEvents, ...args: any[]) {
|
||||||
return ipcRenderer.invoke(event, ...args) as Promise<T>;
|
return ipcRenderer.invoke(event, ...args) as Promise<T>;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { contextBridge, ipcRenderer } from "electron";
|
import { contextBridge, ipcRenderer } from "electron/renderer";
|
||||||
import type { UpdateInfo } from "electron-updater";
|
import type { UpdateInfo } from "electron-updater";
|
||||||
import { UpdaterIpcEvents } from "shared/IpcEvents";
|
import { UpdaterIpcEvents } from "shared/IpcEvents";
|
||||||
|
|
||||||
|
|||||||
@@ -32,3 +32,14 @@ customSettingsSections.push(() => ({
|
|||||||
element: SettingsUi,
|
element: SettingsUi,
|
||||||
className: "vc-vesktop-settings"
|
className: "vc-vesktop-settings"
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// TODO: remove this legacy workaround once some time has passed
|
||||||
|
// @ts-expect-error
|
||||||
|
if (!Vencord.Api.Styles.vencordRootNode) {
|
||||||
|
const style = document.createElement("style");
|
||||||
|
style.id = "vesktop-css-core";
|
||||||
|
|
||||||
|
VesktopNative.app.getRendererCss().then(css => (style.textContent = css));
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => document.documentElement.append(style), { once: true });
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,10 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const enum IpcEvents {
|
export const enum IpcEvents {
|
||||||
GET_VENCORD_PRELOAD_FILE = "VCD_GET_VC_PRELOAD_FILE",
|
GET_VENCORD_PRELOAD_SCRIPT = "VCD_GET_VC_PRELOAD_SCRIPT",
|
||||||
|
DEPRECATED_GET_VENCORD_PRELOAD_SCRIPT_PATH = "DEPRECATED_GET_VENCORD_PRELOAD_SCRIPT_PATH",
|
||||||
GET_VENCORD_RENDERER_SCRIPT = "VCD_GET_VC_RENDERER_SCRIPT",
|
GET_VENCORD_RENDERER_SCRIPT = "VCD_GET_VC_RENDERER_SCRIPT",
|
||||||
GET_RENDERER_SCRIPT = "VCD_GET_RENDERER_SCRIPT",
|
|
||||||
GET_RENDERER_CSS_FILE = "VCD_GET_RENDERER_CSS_FILE",
|
GET_VESKTOP_RENDERER_SCRIPT = "VCD_GET_RENDERER_SCRIPT",
|
||||||
|
GET_VESKTOP_RENDERER_CSS = "VCD_GET_RENDERER_CSS",
|
||||||
|
VESKTOP_RENDERER_CSS_UPDATE = "VCD_PRELOAD_RENDERER_CSS_UPDATE",
|
||||||
|
|
||||||
GET_VERSION = "VCD_GET_VERSION",
|
GET_VERSION = "VCD_GET_VERSION",
|
||||||
SUPPORTS_WINDOWS_TRANSPARENCY = "VCD_SUPPORTS_WINDOWS_TRANSPARENCY",
|
SUPPORTS_WINDOWS_TRANSPARENCY = "VCD_SUPPORTS_WINDOWS_TRANSPARENCY",
|
||||||
|
|||||||
Reference in New Issue
Block a user