A month ago I disclosed a macOS privacy protections bypass, and I offered a sample app for download that demonstrates the issue. Unfortunately, it turns out that the app had a little bug. In applicationDidFinishLaunching
it calls CFPreferencesSetValue(KeepsWindowsOpenPref, kCFBooleanTrue, kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)
, and in applicationWillTerminate
it calls CFPreferencesSetValue(KeepsWindowsOpenPref, kCFBooleanFalse, kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)
, where KeepsWindowsOpenPref = CFSTR("NSQuitAlwaysKeepsWindows")
. The bug is that kCFPreferencesCurrentHost
should have been kCFPreferencesAnyHost
.
How would this bug affect you? The preference NSQuitAlwaysKeepsWindows
corresponds to "Close windows when quitting an app" in the General pane of System Preferences. The app was only supposed to change the value, but the bug caused the app to override the value. As a result, changing the value in System Preferences has no effect. Luckily, there's an easy fix! Just enter the following command in Terminal:
How do you know whether you're affected? Enter this command:
defaults -currentHost read -globalDomain NSQuitAlwaysKeepsWindowsIf the result is "The domain/default pair of (kCFPreferencesAnyApplication, NSQuitAlwaysKeepsWindows) does not exist", then you're fine. But if you see a value (1 or 0), then you'll probably want to delete it.
The file ~/Library/Preferences/.GlobalPreferences.plist
contains the value of NSQuitAlwaysKeepsWindows
if you change "Close windows when quitting an app" in System Preferences. However, if ~/Library/Preferences/ByHost/
happens to contain a preference, that preference overrides the preference in ~/Library/Preferences/
, and that's what happened with my sample app. Deleting the per-host value restores control to ~/Library/Preferences/.GlobalPreferences.plist
.
To be honest, I've never fully understood the function of "host" preferences. Which is why I messed up the sample app a bit. I apologize for any inconvenience! My penance is that I spent all morning debugging this problem until I found the cause and the solution.