Skip to content

Commit a30c76d

Browse files
rdmarsh2GitHub Enterprise
authored and
GitHub Enterprise
committed
Merge pull request github#16 from rdmarsh/rdmarsh/js/electron-unsafe-web-preferences
JavaScript: Add query for disabling webSecurity in Electron
2 parents 25cc89d + b1d8c86 commit a30c76d

File tree

13 files changed

+151
-1
lines changed

13 files changed

+151
-1
lines changed

change-notes/1.18/analysis-javascript.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
| **Query** | **Tags** | **Purpose** |
2222
|-----------------------------|-----------|--------------------------------------------------------------------|
23-
| Use of externally-controlled format string (`js/tainted-format-string`) | security, external/cwe/cwe-134 | Highlights format strings containing user-provided data, indicating a violation of [CWE-134](https://cwe.mitre.org/data/definitions/134.html). Results shown on lgtm by default. |
23+
| Disabling Electron webSecurity (`js/disabling-electron-websecurity`) | security, frameworks/electron | Highlights Electron browser objects that are created with the `webSecurity` property set to false. Results shown on LGTM by default. |
24+
| Use of externally-controlled format string (`js/tainted-format-string`) | security, external/cwe/cwe-134 | Highlights format strings containing user-provided data, indicating a violation of [CWE-134](https://cwe.mitre.org/data/definitions/134.html). Results shown on LGTM by default. |
2425

2526
## Changes to existing queries
2627

javascript/config/suites/javascript/frameworks-more

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@
2121
+ semmlecode-javascript-queries/React/InconsistentStateUpdate.ql: /Frameworks/React
2222
+ semmlecode-javascript-queries/React/UnsupportedStateUpdateInLifecycleMethod.ql: /Frameworks/React
2323
+ semmlecode-javascript-queries/React/UnusedOrUndefinedStateProperty.ql: /Frameworks/React
24+
+ semmlecode-javascript-queries/Electron/DisablingWebSecurity.ql: /Frameworks/Electron
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
<p>
8+
Electron is secure by default through a same-origin policy requiring all
9+
JavaScript and CSS code to originate from the machine running the
10+
Electron application. Setting the <code>webSecurity</code> property of a
11+
<code>webPreferences</code> object to <code>false</code> will disable the
12+
same-origin policy.
13+
</p>
14+
<p>
15+
Disabling the same-origin policy is strongly discouraged.
16+
</p>
17+
</overview>
18+
19+
<recommendation>
20+
<p>
21+
Do not disable <code>webSecurity</code>.
22+
</p>
23+
</recommendation>
24+
25+
<example>
26+
<p>
27+
The following example shows <code>webSecurity</code> being disabled.
28+
</p>
29+
<sample src="examples/DisablingWebSecurity.js"/>
30+
31+
<p>
32+
This is problematic, since it allows the execution of insecure code from
33+
other domains.
34+
</p>
35+
36+
</example>
37+
38+
<references>
39+
<li>Electron Documentation: <a href="https://electronjs.org/docs/tutorial/security#5-do-not-disable-websecurity">Security, Native Capabilities, and Your Responsibility</a></li>
40+
</references>
41+
</qhelp>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* @name Disabling Electron webSecurity
3+
* @description Disabling webSecurity can cause critical security vulnerabilities.
4+
* @kind problem
5+
* @problem.severity error
6+
* @precision very-high
7+
* @tags security
8+
* frameworks/electron
9+
* @id js/disabling-electron-websecurity
10+
*/
11+
12+
import javascript
13+
14+
from DataFlow::PropWrite webSecurity, Electron::WebPreferences preferences
15+
where webSecurity = preferences.getAPropertyWrite("webSecurity")
16+
and webSecurity.getRhs().mayHaveBooleanValue(false)
17+
select webSecurity, "Disabling webSecurity is strongly discouraged."
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const mainWindow = new BrowserWindow({
2+
webPreferences: {
3+
webSecurity: false
4+
}
5+
})

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import semmle.javascript.frameworks.Babel
5252
import semmle.javascript.frameworks.Credentials
5353
import semmle.javascript.frameworks.CryptoLibraries
5454
import semmle.javascript.frameworks.DigitalOcean
55+
import semmle.javascript.frameworks.Electron
5556
import semmle.javascript.frameworks.jQuery
5657
import semmle.javascript.frameworks.LodashUnderscore
5758
import semmle.javascript.frameworks.HttpFrameworks
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import javascript
2+
3+
module Electron {
4+
/**
5+
* A data flow node that is an Electron `webPreferences` property.
6+
*/
7+
class WebPreferences extends DataFlow::ObjectLiteralNode {
8+
WebPreferences() {
9+
exists(BrowserObject bo | this = bo.getOptionArgument(0, "webPreferences").getALocalSource())
10+
}
11+
}
12+
13+
/**
14+
* A data flow node that creates a new `BrowserWindow` or `BrowserView`.
15+
*/
16+
private abstract class BrowserObject extends DataFlow::NewNode {
17+
}
18+
19+
/**
20+
* A data flow node that creates a new `BrowserWindow`.
21+
*/
22+
class BrowserWindow extends BrowserObject {
23+
BrowserWindow() {
24+
this = DataFlow::moduleMember("electron", "BrowserWindow").getAnInstantiation()
25+
}
26+
}
27+
28+
/**
29+
* A data flow node that creates a new `BrowserView`.
30+
*/
31+
class BrowserView extends BrowserObject {
32+
BrowserView() {
33+
this = DataFlow::moduleMember("electron", "BrowserView").getAnInstantiation()
34+
}
35+
}
36+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| electron.js:3:36:3:37 | {} |
2+
| electron.js:4:34:4:35 | {} |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from Electron::WebPreferences wp
4+
select wp
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const {BrowserView, BrowserWindow} = require('electron')
2+
3+
new BrowserWindow({webPreferences: {}})
4+
new BrowserView({webPreferences: {}})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
const {BrowserWindow} = require('electron')
2+
3+
function test() {
4+
var unsafe_used = {
5+
webPreferences: {
6+
webSecurity: false,
7+
allowRunningInsecureContent: true,
8+
experimentalFeatures: true,
9+
enableBlinkFeatures: ['ExecCommandInJavaScript'],
10+
blinkFeatures: 'CSSVariables'
11+
}
12+
};
13+
14+
var unsafe_unused = {
15+
webPreferences: {
16+
webSecurity: false,
17+
allowRunningInsecureContent: true,
18+
experimentalFeatures: true,
19+
enableBlinkFeatures: ['ExecCommandInJavaScript'],
20+
blinkFeatures: 'CSSVariables'
21+
}
22+
};
23+
24+
var safe_used = {
25+
webPreferences: {
26+
webSecurity: true,
27+
allowRunningInsecureContent: false,
28+
experimentalFeatures: false,
29+
enableBlinkFeatures: [],
30+
blinkFeatures: ''
31+
}
32+
};
33+
34+
new BrowserWindow(unsafe_used);
35+
new BrowserWindow(safe_used);
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| DangerousWebPreferences.js:6:13:6:30 | webSecurity: false | Disabling webSecurity is strongly discouraged. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Electron/DisablingWebSecurity.ql

0 commit comments

Comments
 (0)