Programatic configuration of Safari 11 "Websites" preferences tab.

MrP
Contributor III

Has anyone figured out how to configure the Camera and Microphone options programmatically? The configuration for "When visiting other websites" under "Camera" and "Microphone" do not appear to be stored in ~ com.apple.Safari. I'm guessing they have been tucked in some sqllite3 db somewhere. I disabled SIP so I could run opensnoop ,hoping to witness the file modification while changing the preferences but came up with nothing.

Has anyone come up with a way to set "When visiting other websites" other than manually?

7 REPLIES 7

MrP
Contributor III

The following was shared with me on another forum. FYI:

It looks as though it is stored in ~/Library/Safari/PerSitePreferences.db (SQLite database) the table is called default_preferences The cell is called preference with value PerSitePreferencesCamera and the default_value is an integer 1 sets it to deny. So you should be able to programmatically set it for the user, though I see no way of ‘Locking’ it meaning the user could change it.

MrP
Contributor III
#!/bin/bash

# Get user logged into console and put into variable "user"
user=`ls -l /dev/console | cut -d " " -f 4`

##
# Safari: Disabling the "Per site preferences" 
##
#Location of the Safari Per Site Preferences db for the current user
db="/Users/$user/Library/Safari/PerSitePreferences.db"

# Inserting known values into db and ignoring errors(should the entries already exist).  Setting all to "deny"
## This is done because these values don't exist until safari uses this function.  We don't want to wait for this to lock it down.
sudo -u $user sqlite3 $db "INSERT INTO default_preferences ( preference, default_value ) values ( 'PerSitePreferencesAutoplay','1');" 2> /dev/null
sudo -u $user sqlite3 $db "INSERT INTO default_preferences ( preference, default_value ) values ( 'PerSitePreferencesMicrophone','1');" 2> /dev/null
sudo -u $user sqlite3 $db "INSERT INTO default_preferences ( preference, default_value ) values ( 'PerSitePreferencesCamera','1');" 2> /dev/null

# Finding current entries in DB which are not set to deny and setting them to deny as needed
currentSettings=`sqlite3 $db 'select * from default_preferences;' 2> /dev/null` 
for line in $currentSettings; do
    # If the current setting is not 1(Deny) set to deny.
    if [[ $line != *"|1" ]]; then
        line=`echo "$line" | awk -F "|" '{print $2}'`
        echo "$line is not set to 1(Disabled).  Disabling..."
        sudo -u $user sqlite3 $db "update default_preferences set default_value = '1' where preference = '$line';"
        echo -n New Value: 
        sqlite3 $db 'select * from default_preferences;' | grep $line
    fi
done
    # The following file contains any permissions for remote sites to interact with the camera, microphone, location services, etc, that deviate from the default 'deny' permission.  By removing it sites will be denied by default.
    plist="/Users/$user/Library/Safari/UserMediaPermissions.plist"
    if [ -e $plist ]; then echo "User: Safari: Removing User Media Permissions configuration file.";rm -f $plist; fi


echo "User: Safari: Setting 'Allow websites to ask for permission to send push notifications' to no."
sudo -u $user defaults write com.apple.Safari CanPromptForPushNotifications -bool false 
##
# Safari: Disabling per-site push notifications
## 
#We could just delete the preferences file, however should the user view the settings, this provides indication to the user that we do not want them to receive push notifications.
#Location of the Safari Notification Preferences file
plist="/Users/$user/Library/Safari/RemoteNotifications/Permissions.plist"
# Setting all push notifications to Deny.  
notifications=`/usr/libexec/PlistBuddy -c "Print" "$plist" | grep "= Dict" | awk -F = '{print $1}' | perl -pe "s/s*//"| perl -pe "s/ $//"`
for i in $notifications; do
    enabled=`/usr/libexec/PlistBuddy -c "Print ${i}:Remote Notifications Allowed" "$plist"`
    if [ $enabled != 'false' ]; then
        echo $i is allowed to send push notifications.  Disabling..
        sudo -u $user /usr/libexec/PlistBuddy -c "Set ${i}:Remote Notifications Allowed false" "$plist"
        echo Result: Push allowed from $i: `/usr/libexec/PlistBuddy -c "Print ${i}:Remote Notifications Allowed" "$plist"`
    fi
done
plist="/Users/$user/Library/Safari/UserNotificationPermissions.plist"
notifications=`/usr/libexec/PlistBuddy -c "Print" "$plist" | grep "= Dict" | awk -F = '{print $1}' | perl -pe "s/s*//"| perl -pe "s/ $//"`
for i in $notifications; do
    # escaping : so PlistBuddy interprets it correctly.
    a=`echo "$i"| perl -pe "s/:/\\:/"`
    enabled=`/usr/libexec/PlistBuddy -c "Print ${a}:Permission" "$plist"`
    if [ $enabled != '0' ]; then
        echo $i is allowed to send push notifications.  Disabling..
        sudo -u $user /usr/libexec/PlistBuddy -c "Set ${a}:Permission 0" "$plist"
        echo Result: Push allowed from $i: `/usr/libexec/PlistBuddy -c "Print ${a}:Permission" "$plist"`
    fi
done

eDooku
New Contributor III

This is a valid solution to fix the popup window blocker currently enforced in Safari 12 for our internal sites. However, CLI or apps are not even allowed to read the contents of "/Users/$user/Library/Safari" in macOS 10.14 Mojave. Is there, perhaps, another way to update the PerSitePreferences in Safari 12?

daworley
Contributor II

@MrP Thank you very much for your script. It pointed me in the right direction to solve a problem I had.

It seems that the PerSitePreferences.db only allows us to whitelist specific domains, and does not support wildcards or regex to support whitelisting an entire domain.

Does anybody know this trick?

MrP
Contributor III

@eirikw in 10.14, if testing with Terminal, open System Preferences -> Security & Privacy -> Privacy, and add Terminal to Full Disk Access and you will be able to access/modify objects in that folder.

The JSS installs a configuration profile that gives the jamf binary access to this folder. You may also find this utility helpful: https://github.com/jamf/PPPC-Utility

eDooku
New Contributor III

@MrP You are right, of course. I was testing in Terminal, and by running via Self Service. I put Terminal in the Full Disk Access whitelist, and it worked. Then I ran the policy through "sudo jamf policy -event <myCustomTrigger>", and it worked. So, it works, but somehow not through Self Service.

Thank you for pointing me in the right direction!

DMH2000
Contributor

I know this is an old thread, but does anyone out there have a script for adding allowed URL for pop-ups in Safari?

I have a script below, but results come back as DB doesn't exist or Access Denied. 

loggedInUser=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' )
echo $loggedInUser

sudo -u $loggedInUser echo 'insert into preference_values (domain,preference,preference_value) values ("device.login.microsoftonline.com","PerSitePreferencesPopUpWindow",2)'|sqlite3 /Users/$loggedInUser/Library/Safari/PerSitePreferences.db

sudo -u $loggedInUser echo 'insert into preference_values (domain,preference,preference_value) values ("login.microsoftonline.com","PerSitePreferencesPopUpWindow",2)'|sqlite3 /Users/$loggedInUser/Library/Safari/PerSitePreferences.db

exit 0