aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-09-19 00:38:19 +0200
committerLibravatar GitHub <noreply@github.com>2021-09-19 00:38:19 +0200
commit40e007d6a4de9b4c0be49eb5f2d4f1706eaf801d (patch)
treef4b1a7f0ff2bf54b7d1b7bc1e050e2786fbfd219 /src
parentchore: removed 'first-time-contributors' GH workflow since that is not workin... (diff)
downloadferdium-app-40e007d6a4de9b4c0be49eb5f2d4f1706eaf801d.tar.gz
ferdium-app-40e007d6a4de9b4c0be49eb5f2d4f1706eaf801d.tar.zst
ferdium-app-40e007d6a4de9b4c0be49eb5f2d4f1706eaf801d.zip
security: do not expose electron API to services (#1964)
* security: do not expose electron API to services Service code running the the main world should not have access to any electron API. This still allows recipes from webview.js accessing these APIs through the @electron/remote module and/or the Ferdi object, but webview-unsafe.js and the untrusted code coming from the service will not have any access. Currently, no recipe accesses these APIs in its webview-unsafe.js, so the change should not break any recipes. * Expose electron API through the Ferdi object Instead of the unsafe window.ferdi in the main world, we should expose functionality to recipes through the RecipeWebview class. * Update CHANGELOG.md
Diffstat (limited to 'src')
-rw-r--r--src/webview/lib/RecipeWebview.js32
-rw-r--r--src/webview/recipe.js16
2 files changed, 37 insertions, 11 deletions
diff --git a/src/webview/lib/RecipeWebview.js b/src/webview/lib/RecipeWebview.js
index 4085b925b..a4951ed69 100644
--- a/src/webview/lib/RecipeWebview.js
+++ b/src/webview/lib/RecipeWebview.js
@@ -1,12 +1,14 @@
1import { ipcRenderer } from 'electron'; 1import { ipcRenderer } from 'electron';
2import { BrowserWindow, desktopCapturer, getCurrentWebContents } from '@electron/remote';
2import { pathExistsSync, readFileSync, existsSync } from 'fs-extra'; 3import { pathExistsSync, readFileSync, existsSync } from 'fs-extra';
3 4
4const debug = require('debug')('Ferdi:Plugin:RecipeWebview'); 5const debug = require('debug')('Ferdi:Plugin:RecipeWebview');
5 6
6class RecipeWebview { 7class RecipeWebview {
7 constructor(badgeHandler, notificationsHandler) { 8 constructor(badgeHandler, notificationsHandler, sessionHandler) {
8 this.badgeHandler = badgeHandler; 9 this.badgeHandler = badgeHandler;
9 this.notificationsHandler = notificationsHandler; 10 this.notificationsHandler = notificationsHandler;
11 this.sessionHandler = sessionHandler;
10 12
11 ipcRenderer.on('poll', () => { 13 ipcRenderer.on('poll', () => {
12 this.loopFunc(); 14 this.loopFunc();
@@ -23,6 +25,26 @@ class RecipeWebview {
23 25
24 darkModeHandler = false; 26 darkModeHandler = false;
25 27
28 // TODO Remove this once we implement a proper wrapper.
29 get ipcRenderer() {
30 return ipcRenderer;
31 }
32
33 // TODO Remove this once we implement a proper wrapper.
34 get desktopCapturer() {
35 return desktopCapturer;
36 }
37
38 // TODO Remove this once we implement a proper wrapper.
39 get BrowserWindow() {
40 return BrowserWindow;
41 }
42
43 // TODO Remove this once we implement a proper wrapper.
44 get getCurrentWebContents() {
45 return getCurrentWebContents;
46 }
47
26 /** 48 /**
27 * Initialize the loop 49 * Initialize the loop
28 * 50 *
@@ -113,6 +135,14 @@ class RecipeWebview {
113 fn(); 135 fn();
114 } 136 }
115 } 137 }
138
139 clearStorageData(storageLocations) {
140 this.sessionHandler.clearStorageData(storageLocations);
141 }
142
143 releaseServiceWorkers() {
144 this.sessionHandler.releaseServiceWorkers();
145 }
116} 146}
117 147
118export default RecipeWebview; 148export default RecipeWebview;
diff --git a/src/webview/recipe.js b/src/webview/recipe.js
index d7032da3f..32df0f756 100644
--- a/src/webview/recipe.js
+++ b/src/webview/recipe.js
@@ -1,7 +1,6 @@
1/* eslint-disable global-require */ 1/* eslint-disable global-require */
2/* eslint-disable import/first */ 2/* eslint-disable import/first */
3import { contextBridge, desktopCapturer, ipcRenderer } from 'electron'; 3import { contextBridge, ipcRenderer } from 'electron';
4import { BrowserWindow, getCurrentWebContents } from '@electron/remote';
5import { join } from 'path'; 4import { join } from 'path';
6import { autorun, computed, observable } from 'mobx'; 5import { autorun, computed, observable } from 'mobx';
7import { pathExistsSync, readFileSync } from 'fs-extra'; 6import { pathExistsSync, readFileSync } from 'fs-extra';
@@ -109,15 +108,8 @@ contextBridge.exposeInMainWorld('ferdi', {
109 safeParseInt: text => badgeHandler.safeParseInt(text), 108 safeParseInt: text => badgeHandler.safeParseInt(text),
110 displayNotification: (title, options) => 109 displayNotification: (title, options) =>
111 notificationsHandler.displayNotification(title, options), 110 notificationsHandler.displayNotification(title, options),
112 clearStorageData: storageLocations =>
113 sessionHandler.clearStorageData(storageLocations),
114 releaseServiceWorkers: () => sessionHandler.releaseServiceWorkers(), 111 releaseServiceWorkers: () => sessionHandler.releaseServiceWorkers(),
115 getDisplayMediaSelector, 112 getDisplayMediaSelector,
116 getCurrentWebContents,
117 BrowserWindow,
118 ipcRenderer,
119 // TODO: When the discord recipe is changed to use the screenshare.js, this can be removed
120 desktopCapturer,
121}); 113});
122 114
123ipcRenderer.sendToHost( 115ipcRenderer.sendToHost(
@@ -207,7 +199,11 @@ class RecipeController {
207 // Delete module from cache 199 // Delete module from cache
208 delete require.cache[require.resolve(modulePath)]; 200 delete require.cache[require.resolve(modulePath)];
209 try { 201 try {
210 this.recipe = new RecipeWebview(badgeHandler, notificationsHandler); 202 this.recipe = new RecipeWebview(
203 badgeHandler,
204 notificationsHandler,
205 sessionHandler,
206 );
211 // eslint-disable-next-line import/no-dynamic-require 207 // eslint-disable-next-line import/no-dynamic-require
212 require(modulePath)(this.recipe, { ...config, recipe }); 208 require(modulePath)(this.recipe, { ...config, recipe });
213 debug('Initialize Recipe', config, recipe); 209 debug('Initialize Recipe', config, recipe);