About

So, you want to work out what chrome extensions your users have installed, but don’t want to use Google’s Chrome Cloud Managment (free for 1 admin user, but paid after that), what do you do?

This isn’t a sound way to get all extensions installed on a device, it is intended to help gauge the impact on moving to a model where you have a blocklist or an allowlist for chrome extensions.

I think it is often underestimated how much a chrome extension can make an employees’ life easier and going in all guns blazing moving to an allowlist without working out the impact might lead to an uprising, or your employees just trying to avoid these measures.

What do we need?

  • A list of installed extensions on macs
  • A way to process that list into data that is easy to interpret.
  • The extension attribute

    Thanks to this post, I found that the default location of installed chrome extensions is in ~/Library/Application\ Support/Google/Chrome/Default.

    So what do we do from here? my first thought is that we can just ls the directory, chuck commas between each extension ID and echo it into an extension attribute in your chosen MDM.

    Here is how I did it, it’s not necessarily the neatest or best way to do it. But it’s the way that worked for me.

    #!/bin/zsh
    
    currentUser=`ls -l /dev/console | cut -d " " -f4`
    userHome=$( dscl . read /Users/$currentUser NFSHomeDirectory | awk '{print $NF}' )
    
    
    # checking that files dont exist before starting
    if [[ -f /tmp/extensions.txt ]]
    then
        rm /tmp/extensions.txt
    else
        echo "extensions.txt does not already exist"
    fi
    
    if [[ -f /tmp/extensionsNew.txt ]]
    then
        rm /tmp/extensionsNew.txt
    else
        echo "extensions.txt does not already exist"
    fi
    
    
    # gets names of all files in the extensions dir
    if [[ -d $userHome/Library/Application\ Support/Google/Chrome/Default/Extensions ]]
    then
        echo "Extensions dir exists"
        
        ls $userHome/Library/Application\ Support/Google/Chrome/Default/Extensions/ > /tmp/extensions.txt 
        tr '\n' ',' < /tmp/extensions.txt > /tmp/extensionsNew.txt
        extensions=$(cat /tmp/extensionsNew.txt)
    
        echo "<result>"$extensions"</result>"
    
        rm /tmp/extensions.txt
        rm /tmp/extensionsNew.txt
    
        exit 0
    else
        echo "extensions dir does not exist"
        
        exit 0
    fi

    Any suggestions on how the above could be better done are appreciated.

    So now we have our list of extensions into our MDM, we have 2 options:

  • Use their API
  • Export a CSV
  • note, the script that I have written expects only 2 columns and will have to be adapted to expect more than that.

    I decided to use a CSV for this, mostly because having not used my MDM’s API before it would be quicker to import it for this one-off task.

    What does the script do?

  • Loads the CSV and manipulates the data into a json array
  • Checks if the data exists in the extensions_mapper array, if it does add to a known array, if not add to a unknown one
  • If the ID already exists in one of the arrays add 1 to the count
  • Then repeat this for the whole of the origional array
  • Finally write both arrays to file
  • The array that is spat out by the csvLoader() will look something like the below which will also be written into the results/ directory.

    ["id1","id2","id3","id2","id3","id1"]

    Your input/extensions_mapper file should look like the below, obviously you would duplicate this object for each extension, the script then iterates through this array for every extension and works out whether it should add it to the known or unknown list.

    [
        {
            "id":"exampleChromeExtensionID",
            "extension_name":"extension_name",
            "publisher":"nameOfPublisher"
        },
    ]

    If the extension is found in the extensions_mapper array it is referred to as a “Known extension”, otherwise an “Unknown extension”. Below you will see an example of an object that is in the known list:

    [
        {
            "id": "ggjhpefgjjfobnfoldnjipclpcfbgbhl", 
            "extension_name": "My Apps Secure Sign-in Extension", 
            "publisher": "Microsoft", 
            "count": 1
        }
    ]
    ]

    and this is one in the Unknown list:

    [
        {
            "id": "exampleID", 
            "count": 1
        }
    ]

    Hopefully, the info in these 2 arrays will give you enough info for you to start making an assessment as to the impact of blocking an extension in your environment.

    Plans for the future/issues:

    I have come across a fair few extensions that can not be found in the chrome store, so I am thinking of adding a “know_unknown” array to take these out of the unknown list to make it easier to spot new extensions on devices.

    I had a quick go at trying to scrape the chrome store in order to automatically generate the extensionMapper array, but after a quick go it I didn’t have any more time to spend on it, I might revisit this in the future at some point as this would save a lot of time getting this script bootstrapped!

    Where to find this project?

    You can find it on GitHub, any questions ping me a message on the Mac Admins slack

    Followups

    Thanks to Gavin in the #london channel for sharing this talk that gives some background info around the risks of having extensions, some examples of this actually happening and some other ways to deal with these issues.