Managing Browser Settings on macOS

The browser settings for Safari, Chrome, and Firefox can be managed on macOS to lock down home pages and other settings.

Safari

With the release of Safari 10, it looks like Apple no longer allows for MCX-style management of Safari’s preferences. In previous versions, you could easily set a homepage using the following command (ran as the current user):

defaults write com.apple.Safari HomePage "http://HOMEPAGE_URL"

 

MCX preference settings are still supported through configuration profiles. We can create a custom profile with the following attributes:

<?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>PayloadIdentifier</key>
   <string>com.laurenceschool.profile.safari.20161111</string>
   <key>PayloadRemovalDisallowed</key>
   <true/>
   <key>PayloadScope</key>
   <string>System</string>
   <key>PayloadType</key>
   <string>Configuration</string>
   <key>PayloadUUID</key>
   <string>69F2AD5C-A85E-11E6-80F5-76304DEC7EB7</string>
   <key>PayloadOrganization</key>
   <string>Laurence School</string>
   <key>PayloadVersion</key>
   <integer>1</integer>
   <key>PayloadDisplayName</key>
   <string>Safari Home Page</string>
   <key>PayloadContent</key>
   <array>
      <dict>
         <key>PayloadType</key>
         <string>com.apple.ManagedClient.preferences</string>
         <key>PayloadVersion</key>
         <integer>1</integer>
         <key>PayloadIdentifier</key>
         <string>com.laurenceschool.profile.safari.20161113</string>
         <key>PayloadUUID</key>
         <string>E276A24C-A85E-11E6-80F5-76304DEC7EB7</string>
         <key>PayloadEnabled</key>
         <true/>
         <key>PayloadDisplayName</key>
         <string>Sets the Safari HomePage attribute and locks it in place.</string>
         <key>PayloadContent</key>
         <dict>
            <key>com.apple.Safari</key>
            <dict>
               <key>Forced</key>
               <array>
                  <dict>
                     <key>mcx_preference_settings</key>
                        <dict>
                           <key>AlwaysRestoreSessionAtLaunch</key>
                           <false/>
                           <key>NewWindowBehavior</key>
                           <integer>0</integer>
                           <key>NewTabBehavior</key>
                           <integer>0</integer>
                           <key>HomePage</key>
                           <string>http://HOMEPAGE_URL</string>
                        </dict>
                  </dict>
               </array>
            </dict>
         </dict>
      </dict>
   </array>
</dict>
</plist>

 

The profile can then be installed for a specific user through a script:

/usr/bin/profiles -I -F /path/to/profile.mobileconfig -U $USER

 


Google Chrome

The same concept applies for Google Chrome:

<?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>PayloadIdentifier</key>
   <string>com.laurenceschool.profile.chrome.20161113</string>
   <key>PayloadRemovalDisallowed</key>
   <true/>
   <key>PayloadScope</key>
   <string>System</string>
   <key>PayloadType</key>
   <string>Configuration</string>
   <key>PayloadUUID</key>
   <string>6A53E33E-A9E8-11E6-80F5-76304DEC7EB7</string>
   <key>PayloadOrganization</key>
   <string>Laurence School</string>
   <key>PayloadVersion</key>
   <integer>1</integer>
   <key>PayloadDisplayName</key>
   <string>Google Chrome Homepage</string>
   <key>PayloadContent</key>
   <array>
      <dict>
         <key>PayloadType</key>
         <string>com.apple.ManagedClient.preferences</string>
         <key>PayloadVersion</key>
         <integer>1</integer>
         <key>PayloadIdentifier</key>
         <string>com.laurenceschool.profile.chrome.20161113</string>
         <key>PayloadUUID</key>
         <string>BC8C5630-A9E9-11E6-80F5-76304DEC7EB7</string>
         <key>PayloadEnabled</key>
         <true/>
         <key>PayloadDisplayName</key>
         <string>Sets the Chrome HomePage attribute and locks it in place.</string>
         <key>PayloadContent</key>
         <dict>
            <key>com.google.Chrome</key>
            <dict>
               <key>Forced</key>
               <array>
                  <dict>
                     <key>mcx_preference_settings</key>
                     <dict>
                        <key>AutoFillEnabled</key>
                        <false/>
                        <key>DefaultBrowserSettingEnabled</key>
                        <false/>
                        <key>BookmarkBarEnabled</key>
                        <true/>
                        <key>HideWebStorePromo</key>
                        <true/>
                        <key>HomepageIsNewTabPage</key>
                        <false/>
                        <key>HomepageLocation</key>
                        <string>http://HOMEPAGE_URL</string>
                        <key>PasswordManagerEnabled</key>
                        <false/>
                        <key>RestoreOnStartup</key>
                        <integer>4</integer>
                        <key>RestoreOnStartupURLs</key>
                        <array>
                           <string>http://HOMEPAGE_URL</string>
                        </array>
                        <key>ShowHomeButton</key>
                        <true/>
                        <key>SyncDisabled</key>
                        <false/>
                        <key>DefaultNotificationsSetting</key>
                        <integer>2</integer>
                        <key>ImportAutofillFormData</key>
                        <false/>
                        <key>ImportBookmarks</key>
                        <false/>
                        <key>ImportHistory</key>
                        <false/>
                        <key>ImportHomepage</key>
                        <false/>
                        <key>ImportSearchEngine</key>
                        <false/>
                        <key>ImportSavedPasswords</key>
                        <false/>
                     </dict>
                  </dict>
               </array>
            </dict>
         </dict>
      </dict>
   </array>
</dict>
</plist>

 


Firefox

Firefox, however, does not support MCX or Configuration Profile management. There is a third party extension that allows customizing preferences and then exporting them as an add-on package. For our purposes, we will create an override autoconfig.js file inside the app directory itself. The JS file will initially point to a CFG file. This allows us to lock the settings using javascript:

// This file is saved to
// Firefox.app/Contents/Resources/defaults/pref/autoconfig.js
pref("general.config.filename", "firefox.cfg");
pref("general.config.obscure_value", 0);

 

// This file is saved to
// Firefox.app/Contents/Resources/firefox.cfg
 
// Disable updater
lockPref("app.update.enabled", false);
// make absolutely sure it is really off
lockPref("app.update.auto", false);
lockPref("app.update.mode", 0);
lockPref("app.update.service.enabled", false);
 
// Disable Add-ons compatibility checking
clearPref("extensions.lastAppVersion"); 
 
// Don't show 'know your rights' on first run
pref("browser.rights.3.shown", true);
 
// Don't show WhatsNew on first run after every update
pref("browser.startup.homepage_override.mstone", "ignore");
 
// Set default homepage
lockPref("browser.startup.homepage","http://HOMEPAGE_URL");
 
// Disable the internal PDF viewer
pref("pdfjs.disabled", true);
 
// Disable the flash to javascript converter
pref("shumway.disabled", true);
 
// Don't ask to install the Flash plugin
pref("plugins.notifyMissingFlash", false);
 
// Plugin checking
lockPref("plugins.hide_infobar_for_outdated_plugin", true);
clearPref("plugins.update.url");
 
// Health reporter
lockPref("datareporting.healthreport.service.enabled", false);
 
// Telemetry and FHR
lockPref("datareporting.policy.dataSubmissionEnabled", false);
 
// Crash reporter
lockPref("toolkit.crashreporter.enabled", false);
Components.classes["@mozilla.org/toolkit/crash-reporter;1"].getService(Components.interfaces.nsICrashReporter).submitReports = false;
 
// Popup blocker
lockPref("dom.disable_open_during_load", true);
// Popup whitelist
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Services.perms.add(NetUtil.newURI("http://ALLOWED_URL"), "popup", Services.perms.ALLOW_ACTION);
 
// Set default search engine
Components.utils.import("resource://gre/modules/Services.jsm");
var searchService = Services.search;
var engine = searchService.getEngineByName("Google");
searchService.currentEngine = engine;

 

Note: This configuration will reset with each update to the app since Munki will override the actual app. This deployment should be forced to check for the presence of those two files so that it will continue to apply with every Firefox update.

 


 

Signing Configuration Profiles

Custom profiles, or profiles created outside of Profile Manager/Apple Configurator, are not signed. We can sign them manually with a trusted certificate from the Apple Developer program.

Sign in to the Developer portal and download a Mac Developer Application cert. After it’s installed to the keychain, verify that it’s available as a code signing identity:

/usr/bin/security find-identity -p codesigning -v

 

Then use it to sign a profile:

/usr/bin/security cms -S -N "3rd Party Mac Developer Application: NAME (XXXXXX)" -i /path/to/profile.mobileconfig -o /path/to/signedprofile.mobileconfig

 

The resulting profile will now appear verified to the user.