aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2019-03-05 16:20:40 +0100
committerLibravatar Stefan Malzner <stefan@adlk.io>2019-03-05 16:20:40 +0100
commit6e5531ae16d69087856ce7f174ba465bc759394c (patch)
tree510ab3208f045dbe574b53123c752b9d9349d5a3 /src
parentMerge branch 'develop' of https://github.com/meetfranz/franz into develop (diff)
downloadferdium-app-6e5531ae16d69087856ce7f174ba465bc759394c.tar.gz
ferdium-app-6e5531ae16d69087856ce7f174ba465bc759394c.tar.zst
ferdium-app-6e5531ae16d69087856ce7f174ba465bc759394c.zip
feat(App): Add security checks for external URLs
Diffstat (limited to 'src')
-rw-r--r--src/config.js6
-rw-r--r--src/helpers/url-helpers.js15
-rw-r--r--src/index.js6
-rw-r--r--src/stores/AppStore.js11
4 files changed, 36 insertions, 2 deletions
diff --git a/src/config.js b/src/config.js
index a782ad667..479572edb 100644
--- a/src/config.js
+++ b/src/config.js
@@ -62,3 +62,9 @@ export const SETTINGS_PATH = path.join(app.getPath('userData'), 'config');
62 62
63// Replacing app.asar is not beautiful but unforunately necessary 63// Replacing app.asar is not beautiful but unforunately necessary
64export const DICTIONARY_PATH = asarPath(path.join(__dirname, 'dictionaries')); 64export const DICTIONARY_PATH = asarPath(path.join(__dirname, 'dictionaries'));
65
66export const ALLOWED_PROTOCOLS = [
67 'https:',
68 'http:',
69 'ftp:',
70];
diff --git a/src/helpers/url-helpers.js b/src/helpers/url-helpers.js
new file mode 100644
index 000000000..750d1f00c
--- /dev/null
+++ b/src/helpers/url-helpers.js
@@ -0,0 +1,15 @@
1import { URL } from 'url';
2
3import { ALLOWED_PROTOCOLS } from '../config';
4
5const debug = require('debug')('Franz:Helpers:url');
6
7export function isValidExternalURL(url) {
8 const parsedUrl = new URL(url);
9
10 const isAllowed = ALLOWED_PROTOCOLS.includes(parsedUrl.protocol);
11
12 debug('protocol check is', isAllowed, 'for:', url);
13
14 return isAllowed;
15}
diff --git a/src/index.js b/src/index.js
index 0614197a2..0e222c3d6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -34,6 +34,7 @@ import {
34 DEFAULT_WINDOW_OPTIONS, 34 DEFAULT_WINDOW_OPTIONS,
35} from './config'; 35} from './config';
36import { asarPath } from './helpers/asar-helpers'; 36import { asarPath } from './helpers/asar-helpers';
37import { isValidExternalURL } from './helpers/url-helpers';
37/* eslint-enable import/first */ 38/* eslint-enable import/first */
38 39
39const debug = require('debug')('Franz:App'); 40const debug = require('debug')('Franz:App');
@@ -294,7 +295,10 @@ const createWindow = () => {
294 mainWindow.webContents.on('new-window', (e, url) => { 295 mainWindow.webContents.on('new-window', (e, url) => {
295 debug('Open url', url); 296 debug('Open url', url);
296 e.preventDefault(); 297 e.preventDefault();
297 shell.openExternal(url); 298
299 if (isValidExternalURL(url)) {
300 shell.openExternal(url);
301 }
298 }); 302 });
299}; 303};
300 304
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 168aa7e48..f9009af5a 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -8,6 +8,7 @@ import { getDoNotDisturb } from '@meetfranz/electron-notification-state';
8import AutoLaunch from 'auto-launch'; 8import AutoLaunch from 'auto-launch';
9import prettyBytes from 'pretty-bytes'; 9import prettyBytes from 'pretty-bytes';
10import ms from 'ms'; 10import ms from 'ms';
11import { URL } from 'url';
11 12
12import Store from './lib/Store'; 13import Store from './lib/Store';
13import Request from './lib/Request'; 14import Request from './lib/Request';
@@ -19,6 +20,7 @@ import { onVisibilityChange } from '../helpers/visibility-helper';
19import { getLocale } from '../helpers/i18n-helpers'; 20import { getLocale } from '../helpers/i18n-helpers';
20 21
21import { getServiceIdsFromPartitions, removeServicePartitionDirectory } from '../helpers/service-helpers.js'; 22import { getServiceIdsFromPartitions, removeServicePartitionDirectory } from '../helpers/service-helpers.js';
23import { isValidExternalURL } from '../helpers/url-helpers';
22 24
23const debug = require('debug')('Franz:AppStore'); 25const debug = require('debug')('Franz:AppStore');
24 26
@@ -256,7 +258,14 @@ export default class AppStore extends Store {
256 } 258 }
257 259
258 @action _openExternalUrl({ url }) { 260 @action _openExternalUrl({ url }) {
259 shell.openExternal(url); 261 const parsedUrl = new URL(url);
262 debug('open external url', parsedUrl);
263
264 if (isValidExternalURL(url)) {
265 shell.openExternal(url);
266 }
267
268 gaEvent('External URL', 'open', parsedUrl.host);
260 } 269 }
261 270
262 @action _checkForUpdates() { 271 @action _checkForUpdates() {