summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2021-03-12 10:19:14 +0100
committerOskar Nyberg <oskar@mullvad.net>2021-03-24 16:42:37 +0100
commit4437de21ab18a3ede2d067ce90db3c31d0865d82 (patch)
tree2c1da7073862407291d14acc1c1322f1d207bd1c /gui/src
parenta34620a0a6bf807bb465597779051566d06aab20 (diff)
downloadmullvadvpn-4437de21ab18a3ede2d067ce90db3c31d0865d82.tar.xz
mullvadvpn-4437de21ab18a3ede2d067ce90db3c31d0865d82.zip
Prevent renderer access to files outside of build directory
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/main/index.ts69
1 files changed, 47 insertions, 22 deletions
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index d9acc95a42..efbf9a4aa3 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -386,8 +386,11 @@ class ApplicationMain {
// fetching. https://github.com/electron/electron/issues/22995
session.defaultSession.setSpellCheckerDictionaryDownloadURL('https://00.00/');
+ // Blocks scripts in the renderer process from asking for any permission.
this.blockPermissionRequests();
+ // Blocks any http(s) and file requests that aren't supposed to happen.
this.blockRequests();
+ // Blocks navigation since it's not needed.
this.blockNavigation();
this.translations = this.updateCurrentLocale();
@@ -1422,30 +1425,52 @@ class ApplicationMain {
// renderer process are blocked to protect against the potential threat of malicious third party
// dependencies. There are a few exceptions which are described further down.
private blockRequests() {
- session.defaultSession.webRequest.onBeforeRequest(
- { urls: ['*://*/*'] },
- (details, callback) => {
- if (
- process.env.NODE_ENV === 'development' &&
- // Local web server providing assests (index.html, index.js and css files)
- (details.url.startsWith('http://localhost:8080/') ||
- // Automatic reloading performed by the browser-sync module
- details.url.startsWith('http://localhost:35829/browser-sync/') ||
- // Downloading of React and Redux developer tools.
- details.url.startsWith('https://clients2.google.com') ||
- details.url.startsWith('https://clients2.googleusercontent.com'))
- ) {
- callback({});
- } else {
- log.error(`${details.method} request blocked: ${details.url}`);
- callback({ cancel: true });
+ session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
+ if (this.allowFileAccess(details.url) || this.allowDevelopmentRequest(details.url)) {
+ callback({});
+ } else {
+ log.error(`${details.method} request blocked: ${details.url}`);
+ callback({ cancel: true });
- // Throw error in development to notify since this should never happen.
- if (process.env.NODE_ENV === 'development') {
- throw new Error('Web request blocked');
- }
+ // Throw error in development to notify since this should never happen.
+ if (process.env.NODE_ENV === 'development') {
+ throw new Error('Web request blocked');
}
- },
+ }
+ });
+ }
+
+ private allowFileAccess(url: string): boolean {
+ const buildDir = path.normalize(path.join(path.resolve(__dirname), '..', '..'));
+
+ if (url.startsWith('file:')) {
+ // Extract the path from the URL
+ let filePath = decodeURI(new URL(url).pathname);
+ if (process.platform === 'win32') {
+ // Windows paths shouldn't start with a '/'
+ filePath = filePath.replace(/^\//, '');
+ }
+ filePath = path.resolve(filePath);
+
+ return !path.relative(buildDir, filePath).includes('..');
+ } else {
+ return false;
+ }
+ }
+
+ private allowDevelopmentRequest(url: string): boolean {
+ return (
+ process.env.NODE_ENV === 'development' &&
+ // Local web server providing assests (index.html, index.js and css files)
+ (url.startsWith('http://localhost:8080/') ||
+ // Automatic reloading performed by the browser-sync module
+ url.startsWith('ws://localhost:35829/browser-sync') ||
+ url.startsWith('http://localhost:35829/browser-sync/') ||
+ // Downloading of React and Redux developer tools.
+ url.startsWith('devtools://devtools/') ||
+ url.startsWith('chrome-extension://') ||
+ url.startsWith('https://clients2.google.com') ||
+ url.startsWith('https://clients2.googleusercontent.com'))
);
}