Skip to main content

Like a lot of others on here, we are educators that have been having a rash of students loading extensions in Chrome in order to run VPNs, games, etc. After standing on the shoulders of some much better scripters in JAMF Nation, we came up with the below deterrent. There is a never-ending list of extensions, so the question was really: "Do we want to limit their ability to load any extensions, or curb the behavior itself?" We went for 'curb the behavior'.



Most of this is based off of a couple of scripts I snagged here in the following discussion:
my link text



• First we got a list of offending extensions by scanning systems using @chriscollins script for reporting on installed Chrome extensions



• Once we had the nasty extension we wanted too target, we created Smart Groups with @emilykausalik script



• We then built a Restricted Software rules that killed the Chrome and Firefox processes if they were in one of the offending Smart Groups, and it displayed the following message "Your ability to use Google Chrome has been revoked because of a violation of the acceptable use policy." - (we killed Firefox too because the assumption is that the behavior will just jump browsers)



The end result being that the student is then stuck using only Safari to do their schoolwork (the principal has commented that he thinks this may be against the Geneva Convention 😉 ). If they wish to have the blocks on Chrome and Firefox undone they must seek Administrations help.



We simply reverse it by the users browser profile folder out of Application Support, running a new inventory and then finally a 'sudo jamf manage' all from a policy in Self Service only available to Admins.



The end result: Kids don't really like Safari, and it has way less handy extensions and can be managed more strictly with Parental Controls if need be, so we are targeting the behavior without limiting the 'good' extensions coming in.




  • One caveat: We have found that many of these Extensions are getting in when the student logs in to they personal gmail account and it comes over with their profile. So if they act surprised we let them know that is is their responsibility to check this stuff.

@drioux says:



The end result being that the student is then stuck using only Safari to do their schoolwork (the principal has commented that he thinks this may be against the Geneva Convention).


O.o
say what?


Hopefully that was only a joke that was missing a smiley or sarcasm mark?


edited to indicate sarcasm ;-)


Would this include any type of extension at all ?


We have been targeting vpn's, tor's, proxy's, chat functions, etc., but it's really any extension you want to target because you make the custom Smart Groups. I download the target extension, grab the character string that makes up the name; create the Smart Group, and add that Group to my Restricted Software list.



Limiting their Browser choice is an incredible motivator for high schoolers. There's never going to be any way to stay on top of a black list since it changes daily, and a white list can be just as big as teachers find new useful things.


I can't vouch for this method but reading this thread got me wondering if Google already makes extensions manageable. And it looks like they do.



http://www.chromium.org/administrators/policy-list-3#Extensions



You can make a custom configuration profile to manage the Google Chrome preferences you want ALWAYS. They seem to have a good variety of options in regards to extensions so hopefully it covers the scenarios you're dealing with. It also beats having to create multiple smart groups and Extension Attributes.



The only thing I would do is test to make sure this works on already existing profiles (which I imagine it does).



If you do a search there are a few threads on JAMF Nation describing how to manage Google Chrome preferences via configuration profiles.


@drioux
Thanks for the great idea. My question is: after I've gotten both scripts to run and report successfully, and have imported them into the JSS via Casper Admin, what exactly is the next step? I understand your overall methodology, but the specific steps of finding the extensions and creating Smart Groups using the scripts are a little confusing for me.


@kempt




  1. I create smart group from the EA I got from @emilykausalik (each chrome extension gets a new character string):


  2. One I have that smart group reporting I then set up a Restricted Software that scopes to my Smart Groups




Below is a string of screenshots to show my process:



@drioux
Awesome! Last question - how do you correlate the character string to the actual extension name?


note the string at the end of the url in the Chrome store, and the corresponding folder in the Users ~/Library/Applications Support/Google/Chrome/Default/Extensions folder


@drioux
Got it. Now I have the Extension Attribute added, and created the Smart Group using that EA. I have a test computer running my targeted Extension, but it isn't being automatically added to the Smart Group. This is really my first attempt at using Extension Attributes - am I missing a step?


Someone made an EA that reports all extensions, it's out there on the internet somewhere (I can't remember where, sorry). But I could see wanting to have them individually listed if trying to zero in specifically on extension you don't want people using.


@chriscollins posted this one. This lists what extensions the users have, then you must find out the character string



#!/usr/bin/python

## Script: get_chrome_extensions.py
## Author: Christopher Collins (christophercollins@livenation.com)
## Last Change: 2015-07-14
###########################################
##Description: This script searches the last logged in user's installed extensions and submits it to Casper during an inventory report.
###########################################

import os
import json
from Foundation import CFPreferencesCopyAppValue

#Get name of last logged in user so the extension attribute will report information for the user even if they aren't logged in"
lastloggedinuser = CFPreferencesCopyAppValue('lastUserName', 'com.apple.loginwindow')
userchromepath = '/Users/' + lastloggedinuser + '/Library/Application Support/Google/Chrome/'

#Initialize a dictionary to hold the variable names extension developers used if developers localized their extension
internationalized_extensions = {}

#Initialize a directory to hold the names of the installed extensions
installed_extensions = []

#walk the chrome application support folder
for (dirpath, dirnames, filenames) in os.walk(userchromepath):

#Test to see if file is a manifest.json file and then check its name if it is a placeholder name for a localization file (has __MSG)
#If it is a normal name, then add it to the final list. If its not, add it to the internationalized_extensions dictionary to match against a localized messages.json file
for file in filenames:
if ("Extensions" in dirpath and "manifest.json" in file):
manifest = json.load(open(os.path.join(dirpath, file)))
extension_name = manifest.get('name')
name = extension_name
if '__MSG_'not in extension_name:
installed_extensions.append(extension_name)
else:
extension_name = extension_name[6:-2]
if extension_name not in internationalized_extensions:
internationalized_extensions[extension_name] = extension_name
else:
if (("Extensions" and "locales/en" in dirpath) and "messages.json" in file):
manifest = json.load(open(os.path.join(dirpath, file)))
if manifest:
for key in internationalized_extensions.keys():
if manifest.get(key):
extension_name = manifest.get(key).get('message')
installed_extensions.append(extension_name)
else:
if manifest.get(key.lower()):
extension_name = manifest.get(key.lower()).get('message')
installed_extensions.append(extension_name)

print "<result>{}</result>".format(', '.join(sorted(list(set(installed_extensions)))))

EAs are run during inventory updates. You can run sudo jamf recon from the client machine to initiate the inventory update.


Wasn't the script that reports all of them on this thread that you started @emilykausalik?


After students started abusing extensions, we use Chrome config profiles to only allow extensions we whitelist (using the chromium link above to get the syntax right). Very few educational extensions were requested to be whitelisted. So far so good.


@CasperSally thanks for confirming that it was possible. What's being discussed in this thread seems like a lot of extra work for something that can be managed with a custom config profile. Lots of extra smart groups and EAs in what I assume will be a never ending battle.


Again, we are trying to avoid white lists on purpose and instead target the behavior. I understand that a custom config profile would help in some situations, but we are hoping for a different outcome. Helping the kids change their actions, rather than limiting their options


So then why not use the blacklist function? Whitelisting is not the only option available.


Same reason: That just limits the extensions they can run (and you do chase a never ending list), rather then having a bigger consequence. The kids want to use Chrome or Firefox way more then Safari. So if Chrome gets disabled as a result of their own actions, it carries more weight with them then if the evil IT guy blocks them from stuff.



I realize it's not for everyone. But we are happy with how they are reacting to it


Putting the power in the hands of the students, in my opinion, shows them that choices they make on their computers has consequences and they the are responsible for their actions with technology. To me that seems like a really great way to give them some control and teach them to be mindful about the choices they make. I'm a fan.



Also @mm2270 that is indeed the one. My JAMFnation search-fu appears to be weak. And I figured someone else would find it for me ;)


@kempt make sure the user has it loaded in Chrome and is logged in. Then inventory the system.


@CasperSally How exactly are you creating a Chrome Configuration Profile?


This is the most recent thread I could find on this, and I am also a little confused as to how/where to set up a Chrome Configuration Profile. Guess I need the "for dummies" version.



Right now, all I really want to do is blacklist all Chrome extensions for my student MacBooks and prevent them from adding any. That would at least buy me the time to read up and generate a whitelist. Right now I've just restricted the processes for Firefox and Chrome on the student machines.



Or, you know, if OSX would just prompt for admin credentials before installing add-ons like it does with nearly everything else......but I digress.



Appreciate any enlightenment I can get. Thanks.


We are doing a Custom Settings Config Profile. We blacklist all extensions using the manifest located within the .app container as our guide of what is feasible to control (they have a lot). Then we maintain a list of instructor requested and IT tested extensions.



Faculty and Techs had too many issues with inappropriate themes, malicious extensions, and the occasional Nicolas Cage extensions that replaced webpage content leading up to some very unnecessary Help Desk calls. Students have view only access to the Google Sheet as a "store" to select from. Honestly, after the original onslaught of requests it has slowed down to maybe one a month to add. We also mirror the list on our Google Apps for Edu side to keep things consistent.



We found it to be too much of a hassle to track down each "I think a student in my class has an inappropriate extension" when asked what one or the UID of it, the response typically led us to have to call the student down and take the device away wasting instructional time. Spending our field tech time to browse through the list of installed extensions to narrow it down wasn't worth it. That is now a thing of the past.



Faculty can submit a work order request and we typically have it unblocked the same day or day after.



Curt



Domain is "com.google.Chrome"



Sample of our .plist



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ExtensionInstallBlacklist</key>
<array>
<string>*</string>
</array>
<key>ExtensionInstallForcelist</key>
<array/>
<key>ExtensionInstallWhitelist</key>
<array>
<string>jepfaioimehapnjhmjihcbajchcfjfhk</string>
<string>gighmmpiobklfepjocnamgkkbiglidom</string>
<string>hmkomnmahappbhodlbgopniilemgiadf</string>
<string>dgiabkhhpkeimlnjhiadidkgejojcmbj</string>
<string>cambaldalpopjjmpfogbpikpbhembepl</string>
<string>dcjeclnkejmbepoibfnamioojinoopln</string>
<string>kdmmkfaghgcicheaimnpffeeekheafkb</string>
<string>mgmiemnjjchgkmgbeljfocdjjnpjnmcg</string>
<string>alelhddbbhepgpmgidjdcjakblofbmce</string>
<string>alnfdikmbdfgkcbdodjcbmedanjinmkk</string>
</array>
<key>HomepageIsNewTabPage</key>
<false/>
<key>HomepageLocation</key>
<string>http://www.oursupercoolhomepage.com</string>
<key>RestoreOnStartup</key>
<integer>0</integer>
</dict>
</plist>

Reply