Security is paramount when developing applications, particularly those that interact with remote content or manage sensitive data. Ensuring that your application is secure requires more than just following best practices—it's about building a robust system where vulnerabilities are minimized. Below, we delve into a checklist of security recommendations that you should implement to bolster the security of your application, particularly if you are working with platforms like Electron.
Many really well-known apps that you use in your laptop are Electron apps such as Discord, Github Desktop, Whatsapp, Microsoft Visual Studio Code, Slack, Microsoft Teams, Skype, Spotify, ….
Let’s check the top 19 rules to keep your Electron app secure or what to test if you want to perform security testing or bug hunting on some Electron app.
1. Only Load Secure Content
Loading content over HTTPS is crucial to prevent man-in-the-middle attacks, where an attacker could intercept and alter the content being transmitted. Ensure that all external resources, such as APIs and web pages, are loaded securely via HTTPS.
2. Disable Node.js Integration in All Renderers Displaying Remote Content
Node.js integration in renderers can expose your application to various security risks, especially when rendering remote content. By disabling Node.js in these contexts, you prevent potential exploitation of server-side APIs and restrict access to the local file system, which can be critical in reducing attack vectors.
3. Enable Context Isolation in All Renderers
Context isolation is a feature that separates the JavaScript context of your application from the content it displays. This ensures that malicious scripts injected into a renderer cannot access your app’s core APIs, thus protecting your application from cross-site scripting (XSS) attacks.
4. Enable Process Sandboxing
Sandboxing limits the permissions of processes, confining them to a restricted environment. This isolation prevents a compromised renderer process from affecting the rest of your application or the host operating system, significantly reducing the risk of privilege escalation.
5. Use ses.setPermissionRequestHandler()
in All Sessions Loading Remote Content
This method allows you to manage permission requests (like access to geolocation, notifications, etc.) made by content loaded within your application. By controlling these requests, you can prevent malicious content from exploiting user permissions.
6. Do Not Disable webSecurity
webSecurity
is a crucial setting that enforces the same-origin policy and other critical security features. Disabling it can expose your application to XSS and other injection attacks. Keep it enabled to maintain a strong security posture.
7. Define a Content-Security-Policy (CSP) and Use Restrictive Rules
A well-defined CSP restricts the types of content that can be loaded by your application. For example, using script-src 'self'
ensures that only scripts from your domain are executed, reducing the risk of XSS attacks. A strong CSP is a cornerstone of modern web security.
8. Do Not Enable allowRunningInsecureContent
Enabling this option would allow your application to load mixed content (both HTTP and HTTPS), which compromises the security of your app. Always ensure that insecure content is blocked to protect users from potential threats.
9. Avoid Enabling Experimental Features
Experimental features in browsers and web technologies are often not fully tested and may contain vulnerabilities. By refraining from enabling them, you reduce the risk of introducing unstable or insecure components into your application.
10. Do Not Use enableBlinkFeatures
Similar to experimental features, Blink features are part of the rendering engine and can introduce security risks if enabled prematurely. Avoid using these unless absolutely necessary and fully vetted for security implications.
11. <webview>
: Do Not Use allowpopups
Using allowpopups
can lead to security vulnerabilities by enabling pop-up windows that may be used for phishing or delivering malicious content. It’s best to avoid this setting or restrict its use to trusted domains.
12. <webview>
: Verify Options and Params
When using <webview>
elements, ensure that all options and parameters are verified and sanitized. This prevents malicious actors from manipulating them to exploit vulnerabilities in your application.
13. Disable or Limit Navigation
Limiting navigation within your application’s webviews or frames prevents users from being redirected to malicious sites. By controlling which URLs can be loaded, you mitigate the risk of drive-by downloads and phishing attacks.
14. Disable or Limit Creation of New Windows
Restricting the creation of new windows helps control the user environment, preventing potential security issues like spoofing or phishing through new browser windows that mimic trusted interfaces.
15. Do Not Use shell.openExternal
with Untrusted Content
`shell.openExternal` can launch external URLs in the default web browser. If these URLs are untrusted, they can lead users to malicious sites. Ensure that any external links are thoroughly vetted before using this function.
16. Use a Current Version of Electron
Regularly updating Electron to the latest stable version ensures that your application benefits from the latest security patches and improvements. Using outdated versions can expose your application to known vulnerabilities.
17. Validate the Sender of All IPC Messages
Inter-Process Communication (IPC) is used for communication between the main process and renderers in Electron. Always validate the sender of these messages to prevent malicious renderers from executing unauthorized actions.
18. Avoid Usage of the file://
Protocol and Prefer Custom Protocols
The file://
protocol can be exploited to access local files or execute local scripts. Instead, use custom protocols that can be more tightly controlled and secured within the application environment.
19. Check Which Fuses You Can Change
Electron provides "fuses" which are build-time options to disable or enable specific features. Review and adjust these fuses based on your application’s needs to minimize the attack surface. Disabling unused features can significantly enhance security.
Conclusion
Implementing these security practices is essential to protect your application and its users from potential threats. By following this checklist, you are not only complying with security best practices but also actively reducing the risk of common vulnerabilities. Always stay vigilant, and keep security as a priority throughout the development lifecycle of your application.
For more info: https://www.electronjs.org/docs/latest/tutorial/security
Also a cool project to assess your Electron apps: