Skip to content

Commit

Permalink
runfix: Disable node integrations in webview (#3548)
Browse files Browse the repository at this point in the history
  • Loading branch information
lipis committed Feb 5, 2020
1 parent 0a72125 commit 1111b53
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 52 deletions.
20 changes: 10 additions & 10 deletions electron/renderer/src/components/Webviews.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import './Webviews.css';

import React, {Component} from 'react';
import {remote} from 'electron';

import Webview from './Webview';
import {EVENT_TYPE} from '../../../src/lib/eventType';
Expand All @@ -34,15 +33,6 @@ export default class Webviews extends Component {
};
}

componentWillMount() {
remote.ipcMain.on(EVENT_TYPE.WRAPPER.NAVIGATE_WEBVIEW, (event, {accountId, customUrl}) => {
const updatedWebapp = WindowUrl.createWebappUrl(window.location, customUrl);
this.props.updateAccountData(accountId, {
webappUrl: decodeURIComponent(updatedWebapp),
});
});
}

componentWillReceiveProps(nextProps) {
this.setState({canDelete: this._getCanDeletes(nextProps.accounts)});
}
Expand Down Expand Up @@ -112,6 +102,16 @@ export default class Webviews extends Component {

_onIpcMessage = (account, {channel, args}) => {
switch (channel) {
case EVENT_TYPE.WRAPPER.NAVIGATE_WEBVIEW: {
const [customUrl] = args;
const accountId = account.id;
const updatedWebapp = WindowUrl.createWebappUrl(window.location, customUrl);
this.props.updateAccountData(accountId, {
webappUrl: decodeURIComponent(updatedWebapp),
});
break;
}

case EVENT_TYPE.ACCOUNT.UPDATE_INFO: {
const [accountData] = args;
this.props.updateAccountData(account.id, accountData);
Expand Down
2 changes: 1 addition & 1 deletion electron/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ const showMainWindow = async (mainWindowState: WindowStateKeeper.State) => {
webPreferences: {
backgroundThrottling: false,
enableBlinkFeatures: '',
nodeIntegration: true,
nodeIntegration: false,
preload: PRELOAD_JS,
webviewTag: true,
},
Expand Down
6 changes: 1 addition & 5 deletions electron/src/renderer/preload-webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,9 @@ const subscribeToWebappEvents = () => {
});

window.addEventListener(WrapperEvent.NAVIGATION, event => {
const accountId = new URLSearchParams(window.location.search).get('id');
const data = (event as CustomEvent).detail;
if (data) {
ipcRenderer.send(EVENT_TYPE.WRAPPER.NAVIGATE_WEBVIEW, {
accountId,
customUrl: data.url,
});
ipcRenderer.sendToHost(EVENT_TYPE.WRAPPER.NAVIGATE_WEBVIEW, data.url);
}
});
};
Expand Down
41 changes: 24 additions & 17 deletions electron/src/window/WindowUrl.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
/*
* Wire
* Copyright (C) 2020 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

import * as assert from 'assert';
import {WindowUrl} from './WindowUrl';

describe.only('WindowUrl', () => {
describe('WindowUrl', () => {
describe('getUrlQueryString', () => {
it('returns an unescaped string sequence containing the given parameters', () => {
const params = {
const params = new URLSearchParams({
clientType: 'temporary',
enableLogging: '@wireapp/*',
hl: 'en',
};
});
const queryString = WindowUrl.getQueryString(params);
const expectedString = '?clientType=temporary&enableLogging=@wireapp/*&hl=en';
assert.strictEqual(queryString, expectedString);
Expand All @@ -17,9 +36,9 @@ describe.only('WindowUrl', () => {

describe('replaceUrlParams', () => {
it('replaces all query params in a given url string', () => {
const params = {
const params = new URLSearchParams({
clientType: 'overwritten',
};
});
const url = 'https://app.wire.example.com/?clientType=temporary';
const newUrl = WindowUrl.replaceQueryParams(url, params);
const expectedUrl = encodeURIComponent('https://app.wire.example.com/?clientType=overwritten');
Expand All @@ -28,18 +47,6 @@ describe.only('WindowUrl', () => {
});

describe('createWebappUrl', () => {
it('replaces the env parameter of a local file URL with a given URL and merges the parameters', () => {
const localRendererUrl = `file:///D:/dev/projects/wireapp/wire-desktop/electron/renderer/index.html?env=${encodeURIComponent(
'https://wire-webapp-dev.zinfra.io?clientType=permanent&hl=en&enableLogging=@wireapp/*',
)}`;
const customBackendUrl = 'https://app.wire.example.com/?clientType=temporary';
const expectedURL = `file:///D:/dev/projects/wireapp/wire-desktop/electron/renderer/index.html?env=${encodeURIComponent(
'https://app.wire.example.com/?clientType=temporary&hl=en&enableLogging=@wireapp/*',
)}`;
const actual = WindowUrl.createWebappUrl(localRendererUrl, customBackendUrl, true);
assert.strictEqual(actual, expectedURL);
});

it('creates a custom environment webapp URL based on parameters from an existing renderer page', () => {
const rendererPage =
'file:///D:/dev/projects/wireapp/wire-desktop/electron/renderer/index.html?env=https%3A%2F%2Fwire-webapp-dev.zinfra.io%3Fhl%3Den%26enableLogging%3D%40wireapp%2F*';
Expand Down
52 changes: 33 additions & 19 deletions electron/src/window/WindowUrl.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
import * as querystring from 'querystring';
/*
* Wire
* Copyright (C) 2020 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

export class WindowUrl {
static parseParams(url: string): querystring.ParsedUrlQuery {
static parseParams(url: string): URLSearchParams {
const urlObject = new URL(url);
return urlObject.search ? querystring.parse(urlObject.search.substr(1)) : {};
return urlObject.searchParams;
}

static getQueryString(params: querystring.ParsedUrlQuery): string {
return `?${querystring.unescape(querystring.stringify(params))}`;
static getQueryString(params: URLSearchParams): string {
const _params: string[] = [];
params.forEach((value, key) => {
_params.push(`${key}=${value}`);
});
return `?${_params.join('&')}`;
}

static replaceQueryParams(url: string, params: querystring.ParsedUrlQuery): string {
static replaceQueryParams(url: string, params: URLSearchParams): string {
const fullHost = url.split('?')[0];
const unescapedQueryParams = WindowUrl.getQueryString(params);
return encodeURIComponent(`${fullHost}${unescapedQueryParams}`);
}

static createWebappUrl(
localRendererUrl: string,
customBackendUrl: string,
withRendererPage: boolean = false,
): string {
static createWebappUrl(localRendererUrl: string, customBackendUrl: string): string {
const localFileParams = WindowUrl.parseParams(localRendererUrl);
const envUrlParams = WindowUrl.parseParams(localFileParams['env'] as string);
const envUrlParams = WindowUrl.parseParams(localFileParams.get('env') as string);
const customBackendUrlParams = WindowUrl.parseParams(customBackendUrl);
const mergedParams = {...envUrlParams, ...customBackendUrlParams};
const mergedParams = envUrlParams;
customBackendUrlParams.forEach((value, key) => {
mergedParams.set(key, value);
});
const newEnvUrl = WindowUrl.replaceQueryParams(customBackendUrl, mergedParams);

if (withRendererPage === true) {
const cutPattern = '?env=';
const localFilePrefix = `${localRendererUrl.split(cutPattern)[0]}${cutPattern}`;
return `${localFilePrefix}${newEnvUrl}`;
}
return newEnvUrl;
}
}

0 comments on commit 1111b53

Please sign in to comment.