diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6371ecc0..b2d00347 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ Release date: TBD
#### All platforms
- Changed display of unread messages on the team tabbar, they are now shown as bold text
- Reload only the selected tab and keep its URL on "Reload" and "Clear Cache and Reload".
+- Disabled `eval()` function for security improvements.
#### Windows
- Update Mattermost icon for desktop notifications in Windows 10.
diff --git a/src/browser/index.jsx b/src/browser/index.jsx
index 24a1e902..364713ee 100644
--- a/src/browser/index.jsx
+++ b/src/browser/index.jsx
@@ -1,5 +1,9 @@
'use strict';
+window.eval = global.eval = function() {
+ throw new Error("Sorry, Mattermost does not support window.eval() for security reasons.");
+}
+
const React = require('react');
const ReactDOM = require('react-dom');
const ReactBootstrap = require('react-bootstrap');
@@ -428,7 +432,7 @@ var MattermostView = React.createClass({
// Need to keep webview mounted when failed to load.
return (
{ errorView }
-
+
);
}
});
diff --git a/src/browser/settings.jsx b/src/browser/settings.jsx
index d3fd9644..62651296 100644
--- a/src/browser/settings.jsx
+++ b/src/browser/settings.jsx
@@ -1,5 +1,9 @@
'use strict';
+window.eval = global.eval = function() {
+ throw new Error("Sorry, Mattermost does not support window.eval() for security reasons.");
+}
+
const {remote, ipcRenderer} = require('electron');
const settings = require('../common/settings');
diff --git a/src/browser/webview/mattermost.js b/src/browser/webview/mattermost.js
index b9679f60..92ed1043 100644
--- a/src/browser/webview/mattermost.js
+++ b/src/browser/webview/mattermost.js
@@ -4,6 +4,10 @@ const electron = require('electron');
const ipc = electron.ipcRenderer;
const notification = require('../js/notification');
+window.eval = global.eval = function() {
+ throw new Error("Sorry, Mattermost does not support window.eval() for security reasons.");
+}
+
var hasClass = function(element, className) {
var rclass = /[\t\r\n\f]/g;
if ((' ' + element.className + ' ').replace(rclass, ' ').indexOf(className) > -1) {
diff --git a/test/specs/security_test.js b/test/specs/security_test.js
index 1766e083..9c0f22c6 100644
--- a/test/specs/security_test.js
+++ b/test/specs/security_test.js
@@ -76,5 +76,30 @@ describe('application', function() {
});
}, 5000, 'expected a new window')
.windowByIndex(3).isNodeEnabled().should.eventually.be.false;
- })
+ });
+
+ it('should NOT be able to call eval() in any window', function() {
+ env.addClientCommands(this.app.client);
+ const tryEval = (index) => {
+ return this.app.client
+ .windowByIndex(index)
+ .execute(function() {
+ return eval('1 + 1');
+ }).should.eventually.be.rejected;
+ };
+ const tryEvalInSettingsPage = () => {
+ return this.app.client
+ .windowByIndex(0)
+ .loadSettingsPage()
+ .execute(function() {
+ return eval('1 + 1');
+ }).should.eventually.be.rejected;
+ };
+ return Promise.all([
+ tryEval(0),
+ tryEval(1),
+ tryEval(2),
+ tryEvalInSettingsPage()
+ ]);
+ });
});