Extensions have become a must-have on every user’s browser. Since most users are not aware of the power of browser extensions, the responsibility for creating secure browser extensions belongs to you, the developer. Browser vendors also share some responsibility, and are starting to understand how important the security of browser extensions are—for example, Google recently announced safer extension in Chrome 70.
It is a fact that browsers have been increasing user’s security, including the detection of potential threats from extensions. For instance, Chrome scans the Web Store and disables extensions considered unsafe. Also, during the installation process, an extension always asks the user for permissions, and the installation only completes if the user gives consent.
Browser Extensions & Permissions
The permissions are defined in the manifest.json file of the extension, with the “permissions” property, and they can allow access to almost everything that the browser can access, such as cookies or physical storage for example. Extensions can even allow the injection of scripts on other pages’ DOMs, such as cryptocurrency miner code (for instance, the Droidclub Botnet). You can review the complete list of permissions for Chrome.
After installing an extension, it’s always possible to view its permissions on the browser, as is shown in this image.
In this example (Google Docs Offline), the extension can read and write to the user’s clipboard, which may be very attractive from an attacker perspective.
Before installing an extension, make sure that you always confirm that it is downloaded from an official store, that it has a good reputation, and that the permissions that it requests are adequate for its functionality. Please also consider keeping some extensions disabled and only activate them when needed.
If you’re developing an extension, make sure you only set the required permissions and don’t give it unnecessary access. This is an excellent example of the well-known Principle of Least Privilege.
Many Attack Vectors
It is common for extensions to use third-party scripts that are frequently loaded from their original source. This introduces a new attack vector, because if the third party is compromised, the extension is most likely compromised as well. Be very careful with the use of third-party scripts in your extensions.
Access to third-party resources is often performed without SSL/TLS. This is also a vector for compromising the extension. If an attacker is able to intercept traffic between the user and the servers, they can use the cleartext HTTP communication to insert malicious scripts, and the browser loads them without warning the user.
Another frequent privacy issue is the usage of Analytics tools that send data to third parties. That can include sensitive information such as Personally Identifiable Information (PII), social media usage, visited pages, and so on. Developers must avoid this kind of data leakage at any cost, especially with the recent data protection regulations, such as the General Data Protection Regulation (GDPR).
Real Case Scenarios
PBot, an adware written in Python, installs browser extensions in order to place ads on visited web pages, then redirects the user to other websites.
The power of the extensions can put users at risk, either by the installation of extensions that have coding security bugs, by malicious campaigns deployed with phishing, or by malicious websites that lead the user to install evil extensions. Therefore, it is crucial to have security controls in place when developing an extension. Using application security testing tools can also help developers secure their code from the beginning.
Insecure Coding Practices
As an example, we took the Any.do Chrome extension to demonstrate insecure coding practices in the wild. Any.do is a tool that helps users to manage their time. It has more than 271,000 users.
In the official Chrome store, we see that the code was deployed in June 2017, so it is over a year old now.
It requires permissions to “Read and change all your data on the websites you visit.” Why is that necessary?
The user password seems to be saved on the browser window.Storage, encoded with base64. Is this really true?
Apparently so. The previous image is a screenshot of the browser’s console and shows the content of the window.Storage. By decoding the base64, the password is revealed:
The password remains in the window.Storage until the browser is completely shut down and restarted. This is worse for Mac users because Chrome remains open after closing all its windows, and it is only completely shut down when the user forces the application to quit.
Here is the code that removes the password from the local storage.
If the “userPuid” exists in the storage, the “password” is removed; and the “userPuid” is only created when the user logs in. The previous code is executed when the browser starts. When the user logs off, the “userPuid” and “password” items are removed from the storage.
This is clearly an insecure coding practice. No password should be stored on the client, and the username should only be saved when the user chooses to do so.
We made several attempts in the last few months to contact Any.DO, but we did not get a response from them.
Keep in mind that extensions are very powerful. They are without a doubt outstanding tools, but make sure you use them with caution and develop them with the following guidelines in mind:
- Follow the Principle of Least Privilege for permissions
- When possible, avoid third-party scripts
- When possible, avoid analytics tools
- Use SSL/TLS for all requests
- Follow Secure Coding Practices
- Use Application Security testing tools