Create rule S7076: Custom protocols should be preferred over file:// (#4268)
* Create rule S7076 * Add rule text * Add Electron as allowed framework name --------- Co-authored-by: egon-okerman-sonarsource <egon-okerman-sonarsource@users.noreply.github.com> Co-authored-by: Egon Okerman <egon.okerman@sonarsource.com>
This commit is contained in:
parent
d70c3c40c7
commit
da17c23d79
@ -80,6 +80,7 @@
|
|||||||
* TypeScript
|
* TypeScript
|
||||||
* PropTypes
|
* PropTypes
|
||||||
* JSX
|
* JSX
|
||||||
|
* Electron
|
||||||
// PHP
|
// PHP
|
||||||
* Core PHP
|
* Core PHP
|
||||||
* Guzzle
|
* Guzzle
|
||||||
|
24
rules/S7076/javascript/metadata.json
Normal file
24
rules/S7076/javascript/metadata.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"title": "Custom protocols should be preferred over file://",
|
||||||
|
"type": "VULNERABILITY",
|
||||||
|
"status": "ready",
|
||||||
|
"remediation": {
|
||||||
|
"func": "Constant\/Issue",
|
||||||
|
"constantCost": "30min"
|
||||||
|
},
|
||||||
|
"tags": [],
|
||||||
|
"defaultSeverity": "Major",
|
||||||
|
"ruleSpecification": "RSPEC-7076",
|
||||||
|
"sqKey": "S7076",
|
||||||
|
"scope": "All",
|
||||||
|
"defaultQualityProfiles": [
|
||||||
|
"Sonar way"
|
||||||
|
],
|
||||||
|
"quickfix": "unknown",
|
||||||
|
"code": {
|
||||||
|
"impacts": {
|
||||||
|
"SECURITY": "MEDIUM"
|
||||||
|
},
|
||||||
|
"attribute": "COMPLETE"
|
||||||
|
}
|
||||||
|
}
|
104
rules/S7076/javascript/rule.adoc
Normal file
104
rules/S7076/javascript/rule.adoc
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
The `file://` protocol gets more privileges in Electron than in a browser, which allows attackers to load arbitrary files from users' machines. To prevent this, local pages should be served using custom protocols instead.
|
||||||
|
|
||||||
|
== Why is this an issue?
|
||||||
|
|
||||||
|
In Electron, the `file://` protocol gets more privileges than other protocols do, such as `http` and `https`. Among other things, the `file://` protocol allows access to the entire local file system, which can be a security risk if not handled properly.
|
||||||
|
|
||||||
|
If an attacker is able to execute JavaScript within an Electron application that uses `file://` to serve local pages, then they can use this vulnerability to read any file on the user's machine. This works even if the renderer is fully isolated using sandboxing and context isolation.
|
||||||
|
|
||||||
|
By having access to the local file system, an attacker could read sensitive information stored on the user's machine, such as configuration files, credentials, or other sensitive data.
|
||||||
|
|
||||||
|
== How to fix it in Electron
|
||||||
|
|
||||||
|
=== Code examples
|
||||||
|
|
||||||
|
==== Noncompliant code example
|
||||||
|
|
||||||
|
[source,javascript,diff-id=1,diff-type=noncompliant]
|
||||||
|
----
|
||||||
|
const { app, BrowserWindow } = require('electron');
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
});
|
||||||
|
|
||||||
|
win.loadFile(path.join(__dirname, 'index.html')); // Noncompliant
|
||||||
|
});
|
||||||
|
----
|
||||||
|
|
||||||
|
==== Compliant solution
|
||||||
|
|
||||||
|
This solution gives an example implementation of a custom protocol. It may need to be adapted to fit the specific needs of the application.
|
||||||
|
|
||||||
|
[source,javascript,diff-id=1,diff-type=compliant]
|
||||||
|
----
|
||||||
|
onst { app, net, protocol, BrowserWindow } = require('electron');
|
||||||
|
|
||||||
|
protocol.registerSchemesAsPrivileged([{
|
||||||
|
scheme: 'app',
|
||||||
|
privileges: {
|
||||||
|
standard: true,
|
||||||
|
secure: true,
|
||||||
|
supportFetchAPI: true
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
protocol.handle('app', (req) => {
|
||||||
|
const url = new URL(req.url);
|
||||||
|
if (url.hostname === 'local') {
|
||||||
|
const requestedPath = url.pathname.substring(1);
|
||||||
|
|
||||||
|
const pathToServe = path.resolve(__dirname, requestedPath);
|
||||||
|
const relativePath = path.relative(__dirname, pathToServe);
|
||||||
|
if (!relativePath && !relativePath.startsWith('..') && !path.isAbsolute(relativePath)) {
|
||||||
|
return new Response('Only local application files are allowed', {status: 400});
|
||||||
|
}
|
||||||
|
|
||||||
|
return net.fetch(pathToFileURL(pathToServe).toString());
|
||||||
|
} else {
|
||||||
|
// Handle other types of requests
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
});
|
||||||
|
|
||||||
|
win.loadURL("app://local/index.html");
|
||||||
|
});
|
||||||
|
----
|
||||||
|
|
||||||
|
=== How does this work?
|
||||||
|
|
||||||
|
The compliant solution uses a custom protocol. By using this instead of the `file://` protocol, it becomes possible to limit the access to the local file system. In this case, the custom protocol is used to mimic local file requests. However, any request for a local file that is not part of the Electron application will be rejected.
|
||||||
|
|
||||||
|
== Resources
|
||||||
|
=== Documentation
|
||||||
|
|
||||||
|
* Electron - https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols[Avoid usage of the file:// protocol and prefer usage of custom protocols]
|
||||||
|
* Electron - https://www.electronjs.org/docs/latest/api/protocol#protocolhandlescheme-handler[protocol.handle]
|
||||||
|
|
||||||
|
|
||||||
|
ifdef::env-github,rspecator-view[]
|
||||||
|
|
||||||
|
'''
|
||||||
|
== Implementation Specification
|
||||||
|
(visible only on this page)
|
||||||
|
|
||||||
|
=== Message
|
||||||
|
* Change this code to load using a custom protocol.
|
||||||
|
|
||||||
|
=== Highlighting
|
||||||
|
|
||||||
|
Highlight the entire `loadFile` or `loadURL` function call.
|
||||||
|
|
||||||
|
'''
|
||||||
|
== Comments And Links
|
||||||
|
(visible only on this page)
|
||||||
|
|
||||||
|
endif::env-github,rspecator-view[]
|
||||||
|
|
1
rules/S7076/metadata.json
Normal file
1
rules/S7076/metadata.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
Loading…
x
Reference in New Issue
Block a user