Uptycs Blog

Welcome! The Uptycs blog is for security professionals and osquery enthusiasts interested in exploring new ideas in cloud security. We hope you’ll enjoy our blog enough to subscribe and share.

Osquery tutorial: Assessing Chrome extension permissions

In a previous tutorial, we discussed gathering software inventory, including Chrome extensions.

Knowing what you have is half the battle. But once you know what you have, how do you decide what you should keep?

In general, browser extensions are super useful. Extensions like password managers and ad blockers can often increase the security of your environment.

Learn how to use osquery for threat hunting in our free on-demand webinar.

That being said, extensions can and do request multiple permissions to access the browser and the websites being used within them, often for good reasons, and sometimes for shady reasons.

If the reasons are good, it becomes a matter of trusting the extension to be secure, and the vendor to not exploit that level of access. If the reasons are bad, it’s a good enough reason to disallow that extension in your environment.

But how would you get started inventorying Chrome extensions and their permissions using osquery?

There are three goals we’re looking to achieve with an inventory of Chrome extensions:

  • Create a list of Chrome extensions
  • Identify extensions with high privileges
  • Identify extensions with scripts that can run on any website

With this information, we’ll be able to decide which extensions we want to allow everywhere, as well as start looking at extensions that will require extra attention or research.

If any extension is suspected of being malicious, or simply vulnerable, understanding the scope and potential impact will be much easier, as we will understand the level of permissions an attacker could achieve.

The list of Chrome permissions an extension can request can be found here. The first ones to be on the lookout for are those that generate a warning in Chrome.

We’ll be using three osquery tables to achieve our goals. Click on each item below to see its schema.

  • chrome_extensions—This table contains information such as the identifier, name, version, as well as permissions the installed extensions require.
  • users—Since extensions are a per-user concept, we’ll need to join our results to the users table to know which user is using which extension on each system.
  • chrome_extension_content_scripts—This table includes the JavaScript that code extensions contain, and against which websites it can be executed.

Let’s inventory the extensions, their permissions, and scripts, and see which users have them installed.

How to get a basic Chrome extension permissions inventory with osquery

Start by running this query:

SELECT u.username, extensions.name, extensions.identifier, extensions.version, extensions.permissions, extensions.optional_permissions FROM users u CROSS JOIN chrome_extensions extensions USING (uid);

This query will generate the following data, shown here in a spreadsheet for readability:

osquery-chrome-extension-permissions-table1-magnified-v5

Click to see larger version.

As you can see, the permissions field is quite verbose. If we decide to first drill down on permissions all_urls, tabs, and *://*/*, we can add a list of filters by using WHERE and LIKE that will filter on dangerous permissions:

SELECT u.username, extensions.name, extensions.identifier, extensions.version, extensions.permissions, extensions.optional_permissions FROM users u CROSS JOIN chrome_extensions extensions USING (uid) WHERE extensions.permissions LIKE '%%' OR extensions.permissions LIKE '%tabs%' OR extensions.permissions LIKE '*%://*/*%D';

After running the query above, we now have a shorter list of extensions to worry about:

osquery-chrome-extension-permissions-table2v3-crop

Click to see larger version.

As you work down the list from the most dangerous permissions to the still dangerous but lesser ones, you can simply extend your list of filters. Then, you might want to exclude some known good extensions from the results. In this case, using the identifier is the most reliable way. For example, the next query will exclude uBlock Origin from my results, as it is an extension I trust to access my tabs, and the Chrome Media Router, which is a built-in extension.

To make this query easier, we will use a sub-query, so we can separate the evaluation of filters on permissions from the omission of certain identifiers. This lets us filter on dangerous permissions with specific extensions allowed:

SELECT * FROM (SELECT u.username, extensions.name, extensions.identifier, extensions.version, extensions.permissions, extensions.optional_permissions FROM users u CROSS JOIN chrome_extensions extensions USING (uid) WHERE extensions.permissions LIKE '%%' OR extensions.permissions LIKE '%tabs%' OR extensions.permissions LIKE '*%://*/*%D') WHERE identifier != 'cjpalhdlnbpafiamejdnhcphjbkeiagm' AND identifier != 'pkedcjkdefgpdelpbcmbmeomcjbeemfm';

We now have a shorter list of extensions to drill into:

osquery-chrome-extension-permissions-table3-crop

Click to see larger version.

Once you have identified all of the permissions you want to track, and all of the extensions you have approved and want to exclude from the results, you can then configure your centralized osquery data environment to warn you when new results are seen. Be sure to keep an eye on permissions that generate a warning, but also look for URLs to critical domains.

If you use G Suite extensively, an extension could cause a serious compromise even if it only has access to Gmail, so looking for extensions that can read everything is not always sufficient.

The last piece of the puzzle is the JavaScript content of extensions and the permissions of that code. Some extensions manipulate the content of websites, and as such, could have a high security impact on browsers visiting those sites. Fortunately, Chrome allows precise permissions, meaning that if you had an extension meant to enhance the way Google Meet is displayed, it could only have permission to run JavaScript in the context of Google Meet, not every website in the world. The chrome_extension_content_scripts table contains this data, but it must be joined to the chrome_extensions table to get more basic information. That table, as you recall from the earlier examples, needs to be joined to the users table. We will explore how to use chrome_extension_content_scripts in a future tutorial!

At this point you should have a solid understanding of how to inventory Chrome extensions and how to review those that might be dangerous. This lets you create a list of allowed extensions, disallowed extensions, or simply to keep an eye on things. You can use this data with your mobile device management (MDM) tool to push a Chrome profile, a group policy object (GPO) on Windows, or with G Suite’s Chrome Extension Management feature.

Image by photosforyou from Pixabay