Running downloaded user script securely in macOS app

I am looking for guidance on how to run a user script downloaded from a server in a secure fashion. The script itself will be signed to ensure that it has not been modified.

Can we run the script (bash, perl, zsh, etc) from memory in Swift or do we need to write it to a file and then use NSUserUnixTask to run the script?

If we write it to the file, how can we ensure that the script has not been modified between writing to disk and running it?

I am looking for guidance on how to run a user script downloaded from a server in a secure fashion.

Is your app sandboxed?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
The helper app that is responsible for running scripts is sandboxed. The main app is expected to pass the signed script to the scriptRunner app through XPC.
It might help if you described your threat/security model. You say the scripts are signed, but who's signing them and who's writing them? The NSUser*Task classes are meant for scripts the current user put in the Application Scripts folder themselves, by hand. Sandboxed apps can't write to that folder, but can read from it and run the task classes on the entries there. I think the most you're allowed to do is ask for the folder to be created, then reveal it in Finder.
We are writing a daemon that can communicate with a server and provide some basic system info as part of managing multiple devices. The server can pass a script to the daemon to be run on the device to either collect more info or fix an issue. The script is signed by the server using digital certificate of the server and we can can verify the script has not been modified over the network.
We wanted to separate the task of running the script itself into a different executable which can communicate with the daemon using XPC. Now that the script runner has the script, we could write to disk and run it but the script can potentially be modified between writing to disk and running it.

I am not sure if we have the script body and arguments, can we avoid writing to disk altogether and invoke it from memory? If not, is there a secure way for the process to write the script to disk and run it? Or is there another better option altogether?
Given that design I’d probably have the daemon write the script to disk in a place that’s writeable only to root and readable by your runner service. IMO if an attacker has the ability to modify root-owned files, they’ll find easier targets than your product (-:

I am not sure if we have the script body and arguments, can we avoid writing to disk altogether and invoke it from memory?

It depends on the scripting language. Many script implementations will accept a script from stdin.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Running downloaded user script securely in macOS app
 
 
Q