Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to give my sandboxed Mac app read only access to files in ~/Library?

I'm a little confused with the sandbox. Is this possible?

Thanks!

like image 358
dot Avatar asked Jun 08 '12 15:06

dot


People also ask

How do I allow access to files and folders on Mac?

On your Mac, choose Apple menu > System Preferences, click Security & Privacy , then click Privacy. Select Files and Folders. Select the checkbox below an app to allow it to access files and folders in that location.

How do I control app permissions on Mac?

If you later decide to give a denied app access to your Mac, choose Apple menu > System Preferences, click Security & Privacy , click Privacy, click Accessibility, then select the app's checkbox. To remove an app's access to your Mac, deselect the checkbox.

Does sandbox work on Mac?

Overview. The App Sandbox is an access control technology that macOS provides and enforces at the kernel level. The sandbox's primary function is to contain damage to the system and the user's data if the user executes a compromised app.

How do I give a full access to an application on a Mac?

If you're familiar with an app, you can authorise it by clicking Open System Preferences in the alert, then selecting the tickbox for the app in the Privacy pane. If you're unfamiliar with an app or you don't want to give it access to your Mac at that time, click Deny in the alert.


1 Answers

Yes, but it requires a "temporary exception" entitlement. "Temporary" means that it may go away in some future version of the OS, but that's not much of a risk. The bigger problem is that word "exception": It means you will have to justify your use of the entitlement, or the App Store reviewers will probably reject you.

File a bug report explaining exactly what it is you think you ought to be able to do, but can't do today without access to ~/Library, and ideally also start a forum thread on the topic. They may suggest a workaround to use instead of accessing ~/Library (maybe even using private APIs), in which case, do what they say. Or they may say to use the temporary exception for now, in which case, do that. Or they may not respond, in which case you use the temporary exception and cross your fingers. In any case, make sure your App Store submission review notes have a link to the bug report and/or forum thread.

You will have to edit your project's entitlements plist manually to do this, but it's not very hard. Create a com.apple.security.temporary-exception.files.home-relative-path.read-only array, with one string, "/Library/". Like this:

<key>com.apple.security.temporary-exception.files.home-relative-path.read-only</key>
<array>
    <string>/Library/</string>
</array>

The extra / at the end is how the sandbox knows you want to access a directory, rather than a file. If you leave it off, you will get access to all files in ~/Library, which is what you asked for, but not to files in (recursive) subdirectories of ~/Library, like, say, ~/Library/LaunchAgents/com.mycompany.myapp.myoldagent.12345678-ABCD-EF00-1234-567890ABCDEF.plist, which is what you probably want. See File Access Temporary Extensions in the Entitlement Key Reference documentation.

Also, notice that you already have access "for free" to certain things under ~/Library, either because they get copied into your container, or indirectly when you use the appropriate APIs instead of using paths. So, there may be a better way to accomplish what you're doing—e.g., to read files left by a previous non-sandboxed version of your app, you might be able to migrate them into the container and read them there.

One more thing: Just having access to ~/Library doesn't change what NSHomeDirectory(), URLsForDirectory:inDomains:, etc. will return--you'll still get ~/Containers/com.mycompany.myproduct/Data/Library instead. Apple's semi-official recommendation for dealing with this is to use BSD APIs to get the user's real home directory, and the simplest way is this:

const char *home = getpwuid(getuid())->pw_dir;
NSString *path = [[NSFileManager defaultManager] 
                  stringWithFileSystemRepresentation:home
                  length:strlen(home)];
NSURL *url = [NSURL fileURLWithPath:path isDirectory:YES];

A few notes:

  • It's generally not a good idea to call getpwuid too frequently. The best solution is to call this code once early, and then cache the resulting NSURL.
  • This can obviously also be used to get other users' home (and therefore Library) directories, but the App Store almost certainly won't allow any software that actually tries that.
  • The fact that the library is at ~/Library is considered an "implementation detail" that could change one day, which is another reason (on top of the entitlement) that this has to be considered a temporary workaround until Apple provides a real solution to your higher-level problem, and it might be worth mentioning in your review notes.
like image 198
abarnert Avatar answered Nov 02 '22 22:11

abarnert