Skip to content

Commit

Permalink
Fixes doyensec#58: Update checks based on latest webPreferences defaults
Browse files Browse the repository at this point in the history
I went through https://www.electronjs.org/docs/breaking-changes and
looked for all "Default changed" changes.

These now respect the Electron version if known.
  • Loading branch information
baltpeter committed May 23, 2020
1 parent 85896b8 commit a0e8f31
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 14 deletions.
18 changes: 9 additions & 9 deletions src/finder/checks/AtomicChecks/ContextIsolationJSCheck.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { lt } from 'semver';
import { sourceTypes } from '../../../parser/types';
import { severity, confidence } from '../../attributes';

Expand All @@ -9,7 +10,7 @@ export default class ContextIsolationJSCheck {
this.shortenedURL = "https://git.io/Jeu1p";
}

match(astNode, astHelper, scope){
match(astNode, astHelper, scope, electron_version){
if (astNode.type !== 'NewExpression') return null;
if (astNode.callee.name !== 'BrowserWindow' && astNode.callee.name !== 'BrowserView') return null;

Expand All @@ -30,26 +31,25 @@ export default class ContextIsolationJSCheck {
false,
node => (node.key.value === 'contextIsolation' || node.key.name === 'contextIsolation'));

//At the time of writing this check, you always need contextIsolation (trust us!)
//if (preload.length > 0) {
// Prior to Electron 5.0, `contextIsolation` had to be explicitly set to `true`.
if (contextIsolation.length > 0) {
for (const node of contextIsolation) {
// in practice if there are two keys with the same name, the value of the last one wins
// but technically it is an invalid json
// just to be on the safe side show a warning if any value is insecure
if(node.value.value !== true) {
if(node.value.value === false || (lt(electron_version, '5.0.0') && node.value.value !== true)) {
location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false });
}
}
} else {
} else if (lt(electron_version, '5.0.0')) {
location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false });
}
} else {
//No webpreferences

} else if (lt(electron_version, '5.0.0')) {
//No webpreferences and Electron < 5.0.0
location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false });
}

return location;
}
}
}
8 changes: 5 additions & 3 deletions src/finder/checks/AtomicChecks/NodeIntegrationJSCheck.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { lt } from 'semver';
import { sourceTypes } from '../../../parser/types';
import { severity, confidence } from '../../attributes';

Expand All @@ -13,7 +14,7 @@ export default class NodeIntegrationJSCheck {
//nodeIntegrationInWorker Boolean (optional) - Whether node integration is enabled in web workers. Default is false
//nodeIntegrationInSubFrames Boolean (optional) - Whether node integration is enabled in in sub-frames such as iframes. Default is false

match(astNode, astHelper, scope){
match(astNode, astHelper, scope, electron_version){
if (astNode.type !== 'NewExpression') return null;
if (astNode.callee.name !== 'BrowserWindow' && astNode.callee.name !== 'BrowserView') return null;

Expand All @@ -37,7 +38,8 @@ export default class NodeIntegrationJSCheck {
locations = locations.concat(loc);
}

if (!nodeIntegrationFound) {
// Electron versions prior to 5.0.0 defaulted `nodeIntegration` to `true` if not set.
if (lt(electron_version, '5.0.0') && !nodeIntegrationFound) {
locations.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false });
}

Expand All @@ -61,7 +63,7 @@ export default class NodeIntegrationJSCheck {
if ((node.key.value === "sandbox" || node.key.name === "sandbox") && isIdentifier) continue;
if ((nodeIntegrationStrings.includes(node.key.value) || nodeIntegrationStrings.includes(node.key.name)) && !isIdentifier) continue;
}

locations.push({
line: node.key.loc.start.line,
column: node.key.loc.start.column,
Expand Down
5 changes: 3 additions & 2 deletions src/finder/checks/AtomicChecks/RemoteModuleJSCheck.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { lt } from 'semver';
import { sourceTypes } from '../../../parser/types';
import { severity, confidence } from '../../attributes';

Expand All @@ -9,7 +10,7 @@ export default class RemoteModuleJSCheck {
this.shortenedURL = "https://git.io/JvqrQ";
}

match(astNode, astHelper, scope){
match(astNode, astHelper, scope, electron_version){
if (astNode.type !== 'NewExpression') return null;
if (astNode.callee.name !== 'BrowserWindow' && astNode.callee.name !== 'BrowserView') return null;

Expand All @@ -36,7 +37,7 @@ export default class RemoteModuleJSCheck {

if (wasFound) {
return loc;
} else { // default is module 'remote' enabled (assuming nodeIntegration:true), which is a misconfiguration
} else if(lt(electron_version, '9.0.0')) { // default prior to 9.0.0 was module 'remote' enabled (assuming nodeIntegration:true), which is a misconfiguration
return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }];
}
}
Expand Down

0 comments on commit a0e8f31

Please sign in to comment.