Demo
Learn how Cobalt’s Pentest as a Service (PtaaS) model makes you faster, better, and more efficient.
Demo
Learn how Cobalt’s Pentest as a Service (PtaaS) model makes you faster, better, and more efficient.

Introduction to Chrome Browser Extension Security Testing

Browser extensions, plugins, and add-ons are software components that enhance the functionality of existing programs, specifically web browsers. They modify the browser's user interface and interaction with websites, allowing users to customize their browsing experience. This blog highlights the importance of Chrome browser extension security, its work, permissions, testing for vulnerabilities, real-time attack scenarios, and mitigation methods.

Browser extensions, also known as plugins or add-ons, are software components that add functionality to existing computer programs. Browser extensions modify the browser's core user experience by modifying the browser's user interface and interaction with websites.

Chrome Browser extensions extend the functionality of web browsers by allowing users to customize their browsing experience. Browser extensions interact directly with untrusted web content and therefore, extensions are at risk of attack from malicious website operators and active network attackers.

Many extensions interact centrally with all the web pages, creating a large attack surface that attackers can use to exploit vulnerabilities. Various vulnerabilities have been discovered in browser extensions before. One example is the Remote Code Execution (RCE) Vulnerability found in the Cisco WebEx Browser Extension.

With this in mind, it's important to know that Chrome browser extension security is important. We'll look at a high-level overview of how the extension works, Chrome extension permissions, testing for vulnerabilities in Chrome extensions, a real-time attack scenario, and mitigation methods.

 

Chrome Extension nowadays with users

chrome-extension-example                              image1

What happens next:

chrome-browser-extension-security-testing-example

Note: It is best practice to review browser extensions before installing them, as not all of them are secure. 

The power of extensions puts users at risk through extension installations that contain code security flaws, malicious phishing campaigns, or malicious websites that trick users into installing malicious extensions. Therefore, it is crucial to have various security controls in place when developing extensions.  In this blog post, we will focus on chrome browser extensions and how to audit and test them.

As a pentester, it's essential to learn how technology functions before testing. So, before moving on to the security specifics, let's look at a high-level workflow on extension development.

Introduction

Browser extensions are written in JavaScript and loaded by the browser in the background. It has its DOM but can interact with other sites' DOMs. This means that it may compromise other sites'  confidentiality, integrity, and availability (CIA).

Extension layouts look best when visualized and consists of three components. Let’s look at each component in depth.

chrome-browser-extension-security-testing-example-2

Image Source

  1. Content Script: Each content script has direct access to the DOM of a single web page and is thereby exposed to potentially malicious input. However, the content script contains no permissions other than the ability to send messages to the extension core.

To view and debug content scripts in Chrome, you can open the Chrome developer tools menu from Options > More tools > Developer tools OR (Press - Ctrl + Shift + I). 

With developer tools displayed, click the Source tab, then click the Content Scripts tab. Here you can see the running content scripts of the various extensions and set breakpoints to monitor the flow of execution. In our case, we have shown via the Wappalyzer browser extension. 

chrome-browser-extension-security-testing-example-3            chrome-browser-extension-security-testing-example-4

  1. Extension Core: The extension core contains most of the extension privileges/access, but the extension core can only interact with web content via XMLHttpRequest and content scripts. Also, the extension core does not have direct access to the host machine.

  2. Native Binary: The extension allows a native binary that can access the host machine with the user’s full privileges. The native binary interacts with the extension core through the standard Netscape Plugin Application Programming Interface (NPAPI) used by Flash and other browser plug-ins.

Note: Netscape Plugin Application Programming Interface was an application programming interface of the web browsers that allows plugins to be integrated

To obtain the user's full privileges, an attacker must convince the extension to pass malicious input from the content script to the extension's core and from the extension's core to the native binary. This input should exploit the vulnerability.  

After all, the various components of the extension are separated from each other by strong protective boundaries. Each component runs in a separate operating system process. Content scripts and extension cores run in sandbox processes unavailable to most operating system services.  

As a first layer of defense, content scripts seperate from their associated web pages by running in a separate JavaScript heap. The content script and web page have access to the same underlying DOM, but the two never exchange JavaScript pointers, preventing the leaking of JavaScript functionality.

postMessage in Chrome Extensions

chrome-browser-extension-security-testing-example-5

Image Source: OWASPLondon PostMessage Security

  • The Chrome extension uses the postMessage API to Receive messages from external websites (e.g., translation service) or within the same origin (especially developer tools extensions). 

  • You can pass postMessage data into the background script context. Sometimes, it reaches the operating system through native messaging APIs.

Working Extensions & Its Permissions

A Chrome extension is just a ZIP folder with a .crx file extension. The extension's core is the manifest.json file at the root of the folder, which specifies layout, permissions, and other configuration options.

Permissions are defined in the extension's manifest.json file using the "permissions" property and allow access to almost anything a browser can access (Cookies or Physical Storage).

You can see the complete list of Google Chrome permissions before installing them. After installing the extension, you can always check its permissions in your browser, as shown in this image.

chrome-browser-extension-security-testing-example-6

In this example (Wappalyzer), the extension can read your browsing history, which may be very attractive from an attacker’s point of view.  

To find the Extensions root directory say for Windows Operating System (OS), it's (Example: Google Doc Offline) 

C:\Users\<Your_User_Name>\AppData\Local\Google\Chrome\User Data\Default\Extensions\$ID$\version

chrome-browser-extension-security-testing-example-7

Where ID: ghbmnnjooekpmoecnnnilnnbdlolhkhi

  • Enable developer mode (check the developer mode box) and click on the "Pack extension" button.

chrome-browser-extension-security-testing-example-8

How to test Google Chrome extensions?    

Below are some high-level steps to test the Chrome browser extensions for vulnerability assessment and penetration testing.  

  1. Gather Information: Research and understand the extension’s purpose, architecture, and design.

  2. Install in Sandbox Profile: Install the extension in a separate Chrome profile or a virtual machine to ensure that it doesn't interfere with your regular browsing. Make sure you have the latest version of the Chrome browser installed.

  3. Analyze the Source Code: Review the extension's code and documentation to identify potential security vulnerabilities. Look for any suspicious or problematic code, such as code that makes network requests to potentially malicious sites or code that executes with elevated permissions without proper input validation. 

  4. Chrome DevTools: Use a tool like Chrome DevTools to inspect the extension's JavaScript code and any third-party libraries it may use. This can help you identify any vulnerabilities that may be present in the extension's code.

  5. Finding Vulnerability for Success: Use a proxy tool like Burp Suite to intercept and inspect network traffic generated by the extension. This can help you identify any vulnerabilities that may be present in the extension's communication with external servers (if you are on any client engagement, it's good to confirm the API calls used during the extension process flow).

  6. Test for Injections and Cross-site Scripting: Test the extension's input validation and sanitization mechanisms to ensure it correctly handles user input. This can be done by attempting to inject malicious code or payloads into the extension's input fields. 

  7. FuzzAPI: Use a tool like FuzzAPI to test the extension's API endpoints for vulnerabilities automatically. This can help you identify any vulnerabilities that may be present in the extension's API.

  8. Test the Extension's Permissions: You can review the extension's permissions to see if it is requesting any unnecessary or excessive permissions that could be abused.

Note:  These are general guidelines for testing a Chrome browser extension for vulnerabilities. Depending on the specific needs of your testing or extension use case, you may need to take additional steps or use different tools.

Attack Scenarios & Mitigations 

Test Case 1 - Insecure Coding Practice – User password encoded with base64 

When to look:  If you are testing the chrome browser addon, which gives an option for the username and password, you can try to find this bug.  The attacker could read sensitive data by simply accessing the browser memory dump. 


How to find:  Review the source code of the browser extension. 


How to fix:

  • Do not store sensitive data in its raw form (either on disk or in memory). For example, store their hash values instead of the passwords themselves in plaintext when using passwords.

  • It is generally not recommended to store sensitive information, such as passwords, in the browser's local storage due to the potential for access by malicious actors. Instead, consider using server-side storage and implementing proper authentication and authorization measures to secure user accounts.

POC:

To illustrate insecure coding practice, I will use a vulnerability that I found in a Chrome extension with authentication.

Step 1: I analyzed the source code of the browser extension to learn how the authentication process works. To do this, I downloaded the .crx file, change its extension to .zip, and then unzip it.

chrome-browser-extension-security-testing-example-9

Analysis of the source code: 

  • In the logInUsingStoredCredentials function, the username and password are stored in the browser's local storage using the window.storage object. Anyone accessing the user's device can access and retrieve the stored credentials.

  • The password is stored in local storage as a base64-encoded string. 

Step 2:  Login into your browser extension, right-click on it, and click Inspect 

chrome-browser-extension-security-testing-example-10

Step 3: Click the Application tab to open the Application panel. Expand the Local Storage menu.

chrome-browser-extension-security-testing-example-11

Decoding the base64, the password is revealed:

chrome-browser-extension-security-testing-example-12

Test Case 2 - Protect personal and sensitive data stored in a web browser Memory.

When to look: If you are testing the chrome browser extension, which gives an option for the username and password, you can try to find this bug.  The attacker could read sensitive data by simply accessing the browser memory dump. 

How to find: Download and Install the Process Hacker tool and check for strings under the Memory section.

How to fix: Do not store sensitive data in its raw form (either on disk or in memory). For example, store their hash values instead of the passwords themselves in plaintext when using passwords.

Example

int validate(char *username) {

  char *password;

  char *checksum;

  password = read_password();

  checksum = compute_checksum(password);

  erase(password);  /* Securely erase password */

  return !strcmp(checksum, get_stored_checksum(username));

}

Code Explanation:  The function first reads the password entered by the user into the password variable. It then computes a checksum of the password and stores it in the checksum variable. The password is then securely erased using the erase function. Finally, the function compares the computed checksum with the stored checksum associated with the provided username using the strcmp function and returns the comparison result.

Learn more using the reference link.

POC: 

To illustrate the above test case, I will use a vulnerability that I found in a Chrome extension with authentication.

Step 1: Install the addon in your chrome browser and log in with the credentials. 

chrome-browser-extension-security-testing-example-13

Step 2: Open the Process hacker tool => Go to Chrorme.exe

chrome-browser-extension-security-testing-example-14

Step 3: Right-click and go to Properties => Memory => Strings, then click ok.

chrome-browser-extension-security-testing-example-15

The passwords are stored without encryption, meaning they are visible in plain text.

chrome-browser-extension-security-testing-example-16

Test Case 3 – Insecure Randomness 

When to look: Inside the source code. 

How to find: Look in the source code “.js” file and find the Math.random()

How to fix: Consider a PRNG that re-seeds itself as needed from high-quality pseudo-random output sources

References

Test Case 4 – Information Disclosure – Credentials, Credit card or passwords 

When to look: If the browser extension given to you has a feature of a login page or option of entering credit cards or any sensitive data, check for this finding. 

How to find: Go to the option where a password option/credit card option is available. Right-click and inspect the element against the password/credit card functionality and observe the parameter that stores this sensitive data; you will find locally this password and credit card data can be viewed in plain text i.e., secret=” Pass@123”

How to fix: Hide sensitive information such as passwords/credit card details. Do not pass any sensitive information directly to the “secret=” parameter; rather, the developer can use type=password.

Learn more with information from Chromium.


Test Case 5 – Insecure Method used to store sensitive data in URL

When to look: Check for the feature in the browser extension, which can generate data link application/pdf in base64 format (sensitive data), and later browser renders that PDF. Such URLs are logged in the browser and not revoked after the download; attackers can easily access those data from browser history in case of system compromise. 

How to find: Check if your browser extension by anyhow (any feature) generates the data link in base64 format. i.e., data:application/pdf;base64, + pdfData

How to fix:  The browser extensions should revoke such URLs after a time. Also, a developer can use blob:// to download the PDFs and later revoke the link. 

Note: A blob URL or Object-URLs is a particular type of URL that points to a file-like object. It is used to store immutable content such as images, audio, video files, and other types of data. Blob URLs are created by the browser and are not permanent; they expire when the document that created them is closed.

Test Case 6 – Multiple Example Scenario, which you can find during the Chrome browser extension assessment

1x1 – Business Logic Abuse 

The browser extension used for the examination/test generates the URL for the exam test. This single API call only allows us to submit one test at a time, but sharing the same API endpoint in another browser where the extension is installed can allow users to use the same exam multiple times. 

How to Fix: Ensure that the API calls properly verify the steps involved in the test workflow. For example, ensure that once the API is consumed via one user at a time, it should not be re-used by repeating the same request.


1x2 – No Rate Limiting 

The browser extension has a feature to submit feedback or any report. You can check for rate-limiting issues here. 

How to fix: Use a CAPTCHA to limit repeated triggering requests. Use a rate limit per IP address to throttle the repeated triggering requests that can be made in a certain amount of time.


1x3 – Session Token in URL

While browsing the extension, the API generates the session token in the URL. Sensitive information within URLs may be logged in various locations, including the user's browser, the web server, and forward or reverse proxy servers.

How to fix: Avoid putting any sensitive tokens in the URLs. The token can be found in cleartext wherever the URL is stored (eg: within unencrypted log files or browser cache). Instead, sensitive tokens should be sent in the HTTPS headers. Ensure all sensitive data is only transmitted via HTTPS.

Note:  All the vulnerability is impossible to cover, so these are high-level observations.

Tools

Tarnish Chrome Extension Analyzer

Tarnish is a service that helps developers and security researchers audit Chrome extensions for security vulnerabilities, with features such as manifest.json viewer, fingerprint analysis, potential clickjacking analysis, permission warning viewer, dangerous function viewer, and an entry point viewer.

Conclusion

Investigating and examining browser extensions before installation is vital, as some of them may have security risks.

When developing a Chrome extension, follow best practices such as adhering to the Principle of Least Privilege when granting permissions, avoid using third-party scripts if possible, ensure all requests are made over a secure connection using SSL/TLS, follow secure coding practices, and perform application security testing.

Chrome browser extension testing is an important and necessary process to ensure any extension's quality, security, and reliability. By testing an extension thoroughly, developers can ensure that users have a positive experience and that the extension functions properly. Testing can be done manually or with automated tools and should include functional and non-functional tests to ensure the extension meets its desired purpose.


References

New call-to-action

Back to Blog
About Nilesh Sapariya
Nilesh is a highly experienced Penetration Tester with over 10 years of experience in the field. He specializes in testing web applications, mobile applications, cloud infrastructure, thick client systems, conducting source code reviews, and assessing APIs. He has a proven track record of identifying and reporting on zero-day vulnerabilities. Nilesh has successfully led, executed, and managed numerous security assessment projects, from initial planning and testing to final reporting and client deliverables. In his free time, Nilesh participates in bug bounties to stay up to date with the latest vulnerabilities. More By Nilesh Sapariya
A Dive into Client-Side Desync Attacks
A client-side desync, a.k.a CSD, is an attack in which the victim's web browser is tricked into desynchronizing its connection to the vulnerable website. Core Pentester Harsh Bothra takes a look at how attackers can find these vulnerabilities in the wild.
Blog
Jan 16, 2023
Securing Your Digital Footprint Against Hackers
If you’ve ever used the Internet or any online services, it’s more likely than not that you have a digital footprint.
Blog
Mar 15, 2022