diff --git a/javascript/ql/src/Electron/EnablingNodeIntegration.ql b/javascript/ql/src/Electron/EnablingNodeIntegration.ql index 39b19c5d43b..f38d854c1dc 100644 --- a/javascript/ql/src/Electron/EnablingNodeIntegration.ql +++ b/javascript/ql/src/Electron/EnablingNodeIntegration.ql @@ -1,28 +1,32 @@ /** - * @name Enabling nodeIntegration and nodeIntegrationInWorker in webPreferences - * @description Enabling nodeIntegration and nodeIntegrationInWorker could expose your app to remote code execution. + * @name Enabling `nodeIntegration` or `nodeIntegrationInWorker` for Electron web content + * @description Enabling `nodeIntegration` or `nodeIntegrationInWorker` can expose the application to remote code execution. * @kind problem * @problem.severity warning - * @precision very-high + * @id js/enabling-electron-renderer-node-integration * @tags security * frameworks/electron - * @id js/enabling-electron-renderer-node-integration */ import javascript -string checkWebOptions(DataFlow::PropWrite prop, Electron::WebPreferences pref) { - (prop = pref.getAPropertyWrite("nodeIntegration") and - prop.getRhs().mayHaveBooleanValue(true) and - result = "nodeIntegration property may have been enabled on this object that could result in RCE") +/** + * Gets a warning message for `pref` if one of the `nodeIntegration` features is enabled. + */ +string getNodeIntegrationWarning(Electron::WebPreferences pref) { + exists (string feature | + feature = "nodeIntegration" or + feature = "nodeIntegrationInWorker" | + pref.getAPropertyWrite(feature).getRhs().mayHaveBooleanValue(true) and + result = "The `" + feature + "` feature has been enabled." + ) or - (prop = pref.getAPropertyWrite("nodeIntegrationInWorker") and - prop.getRhs().mayHaveBooleanValue(true) and - result = "nodeIntegrationInWorker property may have been enabled on this object that could result in RCE") - or - (not exists(pref.asExpr().(ObjectExpr).getPropertyByName("nodeIntegration")) and - result = "nodeIntegration is enabled by default in WebPreferences object that could result in RCE") + exists (string feature | + feature = "nodeIntegration" | + not exists(pref.getAPropertyWrite(feature)) and + result = "The `" + feature + "` feature is enabled by default." + ) } -from DataFlow::PropWrite property, Electron::WebPreferences preferences -select preferences,checkWebOptions(property, preferences) \ No newline at end of file +from Electron::WebPreferences preferences +select preferences, getNodeIntegrationWarning(preferences) \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.expected b/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.expected index 092ad577de3..674fd74caee 100644 --- a/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.expected +++ b/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.expected @@ -1,5 +1,5 @@ -| EnablingNodeIntegration.js:5:28:11:9 | {\\n ... } | nodeIntegration property may have been enabled on this object that could result in RCE | -| EnablingNodeIntegration.js:5:28:11:9 | {\\n ... } | nodeIntegrationInWorker property may have been enabled on this object that could result in RCE | -| EnablingNodeIntegration.js:15:22:20:9 | {\\n ... } | nodeIntegration is enabled by default in WebPreferences object that could result in RCE | -| EnablingNodeIntegration.js:23:13:27:9 | {\\n ... } | nodeIntegration is enabled by default in WebPreferences object that could result in RCE | -| EnablingNodeIntegration.js:49:71:49:93 | {nodeIn ... : true} | nodeIntegration property may have been enabled on this object that could result in RCE | +| EnablingNodeIntegration.js:5:28:11:9 | {\\n ... } | The `nodeIntegrationInWorker` feature has been enabled. | +| EnablingNodeIntegration.js:5:28:11:9 | {\\n ... } | The `nodeIntegration` feature has been enabled. | +| EnablingNodeIntegration.js:15:22:20:9 | {\\n ... } | The `nodeIntegration` feature is enabled by default. | +| EnablingNodeIntegration.js:23:16:27:9 | { // NO ... } | The `nodeIntegration` feature is enabled by default. | +| EnablingNodeIntegration.js:49:74:49:96 | {nodeIn ... : true} | The `nodeIntegration` feature has been enabled. | diff --git a/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.js b/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.js index fd1a4201df7..5e1d0e95fb4 100644 --- a/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.js +++ b/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.js @@ -1,7 +1,7 @@ const {BrowserWindow} = require('electron') function test() { - var unsafe_1 = { + var unsafe_1 = { // NOT OK, both enabled webPreferences: { nodeIntegration: true, nodeIntegrationInWorker: true, @@ -11,7 +11,7 @@ function test() { } }; - var options_1 = { + var options_1 = { // NOT OK, `nodeIntegrationInWorker` enabled webPreferences: { plugins: true, nodeIntegrationInWorker: false, @@ -20,13 +20,13 @@ function test() { } }; - var pref = { + var pref = { // NOT OK, implicitly enabled plugins: true, webSecurity: true, sandbox: true }; - var options_2 = { + var options_2 = { // NOT OK, implicitly enabled webPreferences: pref, show: true, frame: true, @@ -34,7 +34,7 @@ function test() { minHeight: 300 }; - var safe_used = { + var safe_used = { // NOT OK, explicitly disabled webPreferences: { nodeIntegration: false, plugins: true, @@ -46,6 +46,7 @@ function test() { var w1 = new BrowserWindow(unsafe_1); var w2 = new BrowserWindow(options_1); var w3 = new BrowserWindow(safe_used); - var w4 = new BrowserWindow({width: 800, height: 600, webPreferences: {nodeIntegration: true}}); - var w5 = new BrowserWindow(options_2); -} \ No newline at end of file + var w4 = new BrowserWindow({width: 800, height: 600, webPreferences: {nodeIntegration: true}}); // NOT OK, `nodeIntegration` enabled + var w5 = new BrowserWindow(options_2); + var w6 = new BrowserWindow(safe_used); +} diff --git a/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.qlref b/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.qlref index 3f8dbad0d57..b0315fd89ad 100644 --- a/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.qlref +++ b/javascript/ql/test/query-tests/Electron/NodeIntegration/EnablingNodeIntegration.qlref @@ -1 +1 @@ -../../../../src/Electron/EnablingNodeIntegration.ql \ No newline at end of file +Electron/EnablingNodeIntegration.ql