security: make ipc only allow discord origins
This commit is contained in:
parent
c76d7195a5
commit
9bb02f8581
4 changed files with 74 additions and 48 deletions
|
@ -4,7 +4,7 @@
|
||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { app, dialog, ipcMain, session, shell } from "electron";
|
import { app, dialog, session, shell } from "electron";
|
||||||
import { mkdirSync, readFileSync, watch } from "fs";
|
import { mkdirSync, readFileSync, watch } from "fs";
|
||||||
import { open, readFile } from "fs/promises";
|
import { open, readFile } from "fs/promises";
|
||||||
import { release } from "os";
|
import { release } from "os";
|
||||||
|
@ -17,71 +17,58 @@ import { autoStart } from "./autoStart";
|
||||||
import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants";
|
import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants";
|
||||||
import { mainWin } from "./mainWindow";
|
import { mainWin } from "./mainWindow";
|
||||||
import { Settings } from "./settings";
|
import { Settings } from "./settings";
|
||||||
|
import { handle, handleSync } from "./utils/ipcWrappers";
|
||||||
import { isValidVencordInstall } from "./utils/vencordLoader";
|
import { isValidVencordInstall } from "./utils/vencordLoader";
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.GET_VENCORD_PRELOAD_FILE, e => {
|
handleSync(IpcEvents.GET_VENCORD_PRELOAD_FILE, () => join(VENCORD_FILES_DIR, "vencordDesktopPreload.js"));
|
||||||
e.returnValue = join(VENCORD_FILES_DIR, "vencordDesktopPreload.js");
|
handleSync(IpcEvents.GET_VENCORD_RENDERER_SCRIPT, () =>
|
||||||
});
|
readFileSync(join(VENCORD_FILES_DIR, "vencordDesktopRenderer.js"), "utf-8")
|
||||||
|
);
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.GET_VENCORD_RENDERER_SCRIPT, e => {
|
handleSync(IpcEvents.GET_RENDERER_SCRIPT, () => readFileSync(join(__dirname, "renderer.js"), "utf-8"));
|
||||||
e.returnValue = readFileSync(join(VENCORD_FILES_DIR, "vencordDesktopRenderer.js"), "utf-8");
|
handleSync(IpcEvents.GET_RENDERER_CSS_FILE, () => join(__dirname, "renderer.css"));
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.GET_RENDERER_SCRIPT, e => {
|
handleSync(IpcEvents.GET_SETTINGS, () => Settings.plain);
|
||||||
e.returnValue = readFileSync(join(__dirname, "renderer.js"), "utf-8");
|
handleSync(IpcEvents.GET_VERSION, () => app.getVersion());
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.GET_RENDERER_CSS_FILE, e => {
|
handleSync(
|
||||||
e.returnValue = join(__dirname, "renderer.css");
|
IpcEvents.SUPPORTS_WINDOWS_TRANSPARENCY,
|
||||||
});
|
() => process.platform === "win32" && Number(release().split(".").pop()) >= 22621
|
||||||
|
);
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.GET_SETTINGS, e => {
|
handleSync(IpcEvents.AUTOSTART_ENABLED, () => autoStart.isEnabled());
|
||||||
e.returnValue = Settings.plain;
|
handle(IpcEvents.ENABLE_AUTOSTART, autoStart.enable);
|
||||||
});
|
handle(IpcEvents.DISABLE_AUTOSTART, autoStart.disable);
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.GET_VERSION, e => {
|
handle(IpcEvents.SET_SETTINGS, (_, settings: typeof Settings.store, path?: string) => {
|
||||||
e.returnValue = app.getVersion();
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.SUPPORTS_WINDOWS_TRANSPARENCY, e => {
|
|
||||||
e.returnValue = process.platform === "win32" && Number(release().split(".").pop()) >= 22621;
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on(IpcEvents.AUTOSTART_ENABLED, e => {
|
|
||||||
e.returnValue = autoStart.isEnabled();
|
|
||||||
});
|
|
||||||
ipcMain.handle(IpcEvents.ENABLE_AUTOSTART, autoStart.enable);
|
|
||||||
ipcMain.handle(IpcEvents.DISABLE_AUTOSTART, autoStart.disable);
|
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SET_SETTINGS, (_, settings: typeof Settings.store, path?: string) => {
|
|
||||||
Settings.setData(settings, path);
|
Settings.setData(settings, path);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.RELAUNCH, () => {
|
handle(IpcEvents.RELAUNCH, () => {
|
||||||
app.relaunch();
|
app.relaunch();
|
||||||
app.exit();
|
app.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SHOW_ITEM_IN_FOLDER, (_, path) => {
|
handle(IpcEvents.SHOW_ITEM_IN_FOLDER, (_, path) => {
|
||||||
shell.showItemInFolder(path);
|
shell.showItemInFolder(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.FOCUS, () => {
|
handle(IpcEvents.FOCUS, () => {
|
||||||
if (process.platform === "win32") mainWin.minimize(); // Windows is weird
|
if (process.platform === "win32") mainWin.minimize(); // Windows is weird
|
||||||
|
|
||||||
mainWin.restore();
|
mainWin.restore();
|
||||||
mainWin.show();
|
mainWin.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.CLOSE, e => {
|
handle(IpcEvents.CLOSE, e => {
|
||||||
mainWin.close();
|
mainWin.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.MINIMIZE, e => {
|
handle(IpcEvents.MINIMIZE, e => {
|
||||||
mainWin.minimize();
|
mainWin.minimize();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.MAXIMIZE, e => {
|
handle(IpcEvents.MAXIMIZE, e => {
|
||||||
if (mainWin.isMaximized()) {
|
if (mainWin.isMaximized()) {
|
||||||
mainWin.unmaximize();
|
mainWin.unmaximize();
|
||||||
} else {
|
} else {
|
||||||
|
@ -89,7 +76,7 @@ ipcMain.handle(IpcEvents.MAXIMIZE, e => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => {
|
handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => {
|
||||||
const ses = session.defaultSession;
|
const ses = session.defaultSession;
|
||||||
|
|
||||||
const available = ses.availableSpellCheckerLanguages;
|
const available = ses.availableSpellCheckerLanguages;
|
||||||
|
@ -97,15 +84,15 @@ ipcMain.handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => {
|
||||||
if (applicable.length) ses.setSpellCheckerLanguages(applicable);
|
if (applicable.length) ses.setSpellCheckerLanguages(applicable);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SPELLCHECK_REPLACE_MISSPELLING, (e, word: string) => {
|
handle(IpcEvents.SPELLCHECK_REPLACE_MISSPELLING, (e, word: string) => {
|
||||||
e.sender.replaceMisspelling(word);
|
e.sender.replaceMisspelling(word);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, (e, word: string) => {
|
handle(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, (e, word: string) => {
|
||||||
e.sender.session.addWordToSpellCheckerDictionary(word);
|
e.sender.session.addWordToSpellCheckerDictionary(word);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
||||||
const res = await dialog.showOpenDialog(mainWin!, {
|
const res = await dialog.showOpenDialog(mainWin!, {
|
||||||
properties: ["openDirectory"]
|
properties: ["openDirectory"]
|
||||||
});
|
});
|
||||||
|
@ -117,7 +104,7 @@ ipcMain.handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
||||||
return dir;
|
return dir;
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
|
handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
|
||||||
|
|
||||||
function readCss() {
|
function readCss() {
|
||||||
return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => "");
|
return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => "");
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { desktopCapturer, ipcMain, session, Streams } from "electron";
|
import { desktopCapturer, session, Streams } from "electron";
|
||||||
import type { StreamPick } from "renderer/components/ScreenSharePicker";
|
import type { StreamPick } from "renderer/components/ScreenSharePicker";
|
||||||
import { IpcEvents } from "shared/IpcEvents";
|
import { IpcEvents } from "shared/IpcEvents";
|
||||||
|
|
||||||
|
import { handle } from "./utils/ipcWrappers";
|
||||||
|
|
||||||
export function registerScreenShareHandler() {
|
export function registerScreenShareHandler() {
|
||||||
ipcMain.handle(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, async (_, id: string) => {
|
handle(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, async (_, id: string) => {
|
||||||
const sources = await desktopCapturer.getSources({
|
const sources = await desktopCapturer.getSources({
|
||||||
types: ["window", "screen"],
|
types: ["window", "screen"],
|
||||||
thumbnailSize: {
|
thumbnailSize: {
|
||||||
|
|
36
src/main/utils/ipcWrappers.ts
Normal file
36
src/main/utils/ipcWrappers.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0
|
||||||
|
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
|
||||||
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ipcMain, IpcMainEvent, IpcMainInvokeEvent, WebFrameMain } from "electron";
|
||||||
|
import { IpcEvents } from "shared/IpcEvents";
|
||||||
|
|
||||||
|
export function validateSender(frame: WebFrameMain) {
|
||||||
|
const { hostname, protocol } = new URL(frame.url);
|
||||||
|
if (protocol === "file:") return;
|
||||||
|
|
||||||
|
switch (hostname) {
|
||||||
|
case "discord.com":
|
||||||
|
case "ptb.discord.com":
|
||||||
|
case "canary.discord.com":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("ipc: Disallowed host " + hostname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handleSync(event: IpcEvents, cb: (e: IpcMainEvent, ...args: any[]) => any) {
|
||||||
|
ipcMain.on(event, (e, ...args) => {
|
||||||
|
validateSender(e.senderFrame);
|
||||||
|
e.returnValue = cb(e, ...args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handle(event: IpcEvents, cb: (e: IpcMainInvokeEvent, ...args: any[]) => any) {
|
||||||
|
ipcMain.handle(event, (e, ...args) => {
|
||||||
|
validateSender(e.senderFrame);
|
||||||
|
return cb(e, ...args);
|
||||||
|
});
|
||||||
|
}
|
|
@ -4,8 +4,9 @@
|
||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { app, BrowserWindow, ipcMain, shell } from "electron";
|
import { app, BrowserWindow, shell } from "electron";
|
||||||
import { Settings } from "main/settings";
|
import { Settings } from "main/settings";
|
||||||
|
import { handle } from "main/utils/ipcWrappers";
|
||||||
import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally";
|
import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally";
|
||||||
import { githubGet, ReleaseData } from "main/utils/vencordLoader";
|
import { githubGet, ReleaseData } from "main/utils/vencordLoader";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
|
@ -20,8 +21,8 @@ export interface UpdateData {
|
||||||
|
|
||||||
let updateData: UpdateData;
|
let updateData: UpdateData;
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.UPDATER_GET_DATA, () => updateData);
|
handle(IpcEvents.UPDATER_GET_DATA, () => updateData);
|
||||||
ipcMain.handle(IpcEvents.UPDATER_DOWNLOAD, () => {
|
handle(IpcEvents.UPDATER_DOWNLOAD, () => {
|
||||||
const portable = !!process.env.PORTABLE_EXECUTABLE_FILE;
|
const portable = !!process.env.PORTABLE_EXECUTABLE_FILE;
|
||||||
|
|
||||||
const { assets } = updateData.release;
|
const { assets } = updateData.release;
|
||||||
|
@ -50,7 +51,7 @@ ipcMain.handle(IpcEvents.UPDATER_DOWNLOAD, () => {
|
||||||
shell.openExternal(url);
|
shell.openExternal(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(IpcEvents.UPDATE_IGNORE, () => {
|
handle(IpcEvents.UPDATE_IGNORE, () => {
|
||||||
Settings.store.skippedUpdate = updateData.latestVersion;
|
Settings.store.skippedUpdate = updateData.latestVersion;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue