Sandboxed app placing bash script to shared location for NSUserUnixTask - bad idea?

My app is sandboxed (for submission in the Mac App Store).


In one of the app's functions I need to execute a small bash script.


I tried to use NSTask passing the bash script in one of the arguments. The task launches but unfortunately the script doesn't produce desired results due to sandboxing.


I noticed that if I use NSUserUnixTask and launch the script from a SH file on disk, then the task launches and the script DOES produce the desired result.


Unfortunately, NSUserUnixTask doesn't work if the script file is located inside the app bundle. The file must reside in ~/Library/Application Scripts/<bundle id>/ directory. My app already has read-write access to that folder (the user has granted it), so I thought that I could temporarily copy the bash script file there and launch it with NSUserUnixTask.


However I wonder what are implications of such approach. Obviously, the script can be modified by other software and then my app would execute potentially malicious code. Even if I install the script only for a fraction of a second and remove it immediately after completion, the small theoretical probability that the code could be modified is not entirely excluded.


On the other hand, NSUserUnixTask is SUPPOSED to launch scripts installed from the Application Scripts directory, isn't it? So perhaps it's supposed to be an OK solution?


I wonder how the App Store review team would respond to the above solution. Is it prohibited or may be OK, should I even try?

Nobody other than App Review can tell you how App Review will respond. App Review will only tell you after the fact.


My guess is that it would depend on the nature of your app. If it is using NSUserUnixTask in the manner it was intended, then it should/may be fine. I would have the following concerns:

1) The documentation says that an app can read from, but not write to, FileManager.SearchPathDirectory.applicationScriptsDirectory. If your app violates that, then it could be rejected on that basis alone. I don't know know if allowing the user to grant access would be considered acceptable.

2) The documentation says, FileManager.SearchPathDirectory.applicationScriptsDirectory. If you are accessing the directory ~/Library/Application Scripts/<bundle id> through some other means, the app could be rejected. Furthermore, if you are doing this, the app could break if Apple changes the location. What I'm getting at is that you must use the API.

3) You are correct that a file on disk is not secure. The only way to avoid this is by passing the contents via standard input or directly on the command line, if possible.

4) Why would security be an issue anyway? That suggests that you are not approaching this in the spirit in which it was intended. This functionality is designed to allow end users to expand an app, not to allow an app to escape the sandbox. It doesn't matter if the user is "technically" doing it if you are holding their hand and leading them.

5) What exactly are you trying to do? The sandbox is restricted for good reason. Attempting to circumvent it is not good for security. Nor is it good for your future. If you haven't been paying attention to current Mac/Apple rumours, now would be the time to start. It isn't so much "reading between the lines" as reading the 100 ft. tall billboard. Ask yourself this question. How would your design work on iOS? If it wouldn't work at all, that's a Red Flag. If you are doing this just as a hobby app, or to fluff your resume, or to build a social media presence, then it might be worth the effort. But otherwise, even if Apple gives you the green light, and even if Apple doesn't scrap macOS for iOS, you are essentially wasting your time. Maybe half a dozen people would ever use this feature.

6) One last important plot point. The "sandbox" is not the same as "App Review". Just because the documentation talks about the "sandbox" doesn't mean that has any bearing on App Review. Apple wants ALL apps, even Developer ID apps, to be sandboxed. That is what features like this are designed for. App Review doesn't read documentation. They just say yes or no. If this feature is required for the app to run, or if the apps seems to lead or hand-hold the user towards this functionality, that will be an automatic rejection.

Thanks for the quick answer.


That's why I'm asking it here, I don't want to do anything against the spirit of the documentation. There is however some grey area in it and I want to clarify it for myself.


Let me add additional detail following your bullet points.


I forgot to mention that it's a Mac app.


1. If the app may not write there, this may be a show stopper already. Hmm... But it's not technically enforced, obviously.


2. Yes, I'm using FileManager.SearchPathDirectory.applicationScriptsDirectory, so it's ok.


3. I think there could be some code-signature check of the script in the shared location before it gets executed by NSUserUnixTask. This would securely prevent malicious modification of the script. Is this foreseen somewhere?


4. True, I'm just trying to understand how this shared location for scripts is supposed to work and be safe. Any external script can get modified by any software that has access to that shared folder. So if an app is executing these external scripts, they are basically opaque black boxes for the app, it doesn't know what it's executing. In such case, who is supposed to be responsible for the external scripts' safety? Or am I overthinking it?


5. I'm trying to use "tmutil" command-line utility to manipulate APFS snapshots on macOS. I don't know if it's quite innocent from sandbox's point of view, but unfortunately, tmutil seems to have some additional dependencies that are cut off by the sandbox and consequently the tmutil command fails.


6. Yes, I understand that sandbox is not the same as compliance with App Review.


Is there an alternative way to achieve my goal?


Thanks!

1) Clearly that is talking about default behaviour. If you have a security-scoped bookmark, which NSOpenPanel et al. give you, then that should/may override. App Review may not like it, but that's a different issue. This could be interpreted as a security risk and get fixed one day, thereby breaking your app.


3) That's the race condition. If it is a script, then it have to hand it off to an interpreter. If you use the filesystem for that hand-off, there is a possible exploit.


4) I think you are over-thinking it, and perhaps over-coding it. It is the user that is responsible for the safety of these scripts. They are the ones who copy the files. If you are intending only specific scripts to be run, which may have specific security implications, then you are using this mechanism as a sandbox escape, which is contrary to the spirit of the sandbox as it serves Mac App Store's security goals.


5) I do that in my own app. What I do is contruct the tmutil command and then put it on the pasteboard. Then I give the user instructions and a button that opens terminal. Then I handle an app activate event and assume that the user is coming back from Terminal. But all I know at this point is that the handoff was presented and now the app is reactivated. There is no guarantee that the user did anything or executed any scripts. And the pasteboard is no more secure than the file system.


My app was an accident. I would not recommend any developer take this approach, or even do anything with tmutil. Look for some value that only your app can provide and that you have control over. tmutil is Apple's app. Don't use Apple's apps. You will be burned. Trust me on this one.

Sandboxed app placing bash script to shared location for NSUserUnixTask - bad idea?
 
 
Q