For some years I have developed and maintained a SwiftUI based app as GUI ontop of the command line tool rsync. The app is available on HomeBrew and works as expected, included using rsync command line tool from HomeBrew.
I have now developed a new GUI, a downscale version of the original app, using SwiftData and using only the default rsync in /usr/bin/rsync. No access to remote servers by ssh-keys, only local attached disk on your Mac. SwiftData is used for storing data about synchronise tasks and log records from run.
The app works, but as soon as I enable the App Sandbox, the app does not permit to executed default included command line tool from /usr/bin. The GUI app executes the command line tool by a Swift Process object.
App Sandbox
RSS for tagApp Sandbox is a macOS access control technology designed to contain damage to the system and user data if an app becomes compromised.
Posts under App Sandbox tag
118 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
My sandboxed macOS app requires the user to grant permission under Privacy & Security / Accessibility in order to support extra functionality. If no permission is granted the app can still be used albeit with very basic functionality.
In order to allow the user NOT to have to immediately decide whether to grant this permission when first launching the app, a dialog allows them to say “I’ll do it later”.
As such, the app uses a timer with a one second interval to ask the system if permission has been granted and if so, implements the extra functionality. By the way, I would rather have used a notification instead of a timer, but there does not seem to be one.
// Schedule a timer to periodically check accessibility status
accessibilityTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(checkAccessibilityStatus), userInfo: nil, repeats: true)
func isAccessibilityEnabled() -> Bool {
let accessibilityEnabled = AXIsProcessTrusted()
return accessibilityEnabled
}
@objc func checkAccessibilityStatus() {
if isAccessibilityEnabled() {
print("Accessibility is enabled.")
accessibilityTimer?.invalidate()
if gEventTap == nil {
tapper()//as003
gTypeIt4MeMenu?.item(at: kPauseResumeItem)?.title = "Pause"
gStatusItem?.button!.image = NSImage(named: "menubar_icon_16x16")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "showGreenTick"), object: nil)
}
} else {
print("Accessibility is disabled.")
}
}
My problem is that when I build the app with my development certificate, it runs as expected.
However, when I upload it to TextFlight and download from there, it no longer “notices” when I grant it permission.
To restrict outgoing connections, I've ensured that the following key in not present in the entitlement file:
<key>com.apple.security.network.client</key>
<true/>
The api calls made using URLSession and WKWebView are restricted as expected, but the same is not the case with MKMapView. The map content and the directions api are able to make outgoing network calls.
Please let me know if it's possible to reliably restrict outgoing network connections in a sandboxed app?
I accidentally deleted the DerivedData folder while trying to delete the files to reset the cache. Now Xcode returns following errors regarding with this folder.
I'm using Flutter and Android Studio but building on Xcode to run my app on iPhone.
This project is a ongoing and quite mature project so I have to solve these error. When I open a brand new project in Flutter, it works fine without any error.
Error # 1 : Sandbox: rsync.samba(12046) deny(1) file-write-create /Users/mycompany/Library/Developer/Xcode/DerivedData/Runner-bfdtmaowyaodbagkvttzeqjhiwjl/Build/Products/Debug-iphonesimulator/Flutter.framework
Error # 2 : Sandbox: dart(12019) deny(1) file-write-create /Users/mycompany/Library/Developer/Xcode/DerivedData/Runner-bfdtmaowyaodbagkvttzeqjhiwjl/Build/Products/Debug-iphonesimulator/.last_build_id
Error # 3 : Flutter failed to write to a file at "/Users/mycompany/Library/Developer/Xcode/DerivedData/Runner-bfdtmaowyaodbagkvttzeqjhiwjl/Build/Products/Debug-iphonesimulator/.last_build_id".
According to https://developer.apple.com/documentation/security/app_sandbox/discovering_and_diagnosing_app_sandbox_violations it is possible to view detailed violation reports for non-system services. Is it possible to do something similar for system services?
I have encountered an issue where several (all?) of my Macbooks get into a sandbox violation situation (I assume). Below is in excerpt from logs focusing just on the sandbox violation. The errors are surrounded by XPC failures and errors.
error 23:23:21.382263+0100 kernel Sandbox: Family(1316) deny(1) mach-lookup com.apple.contactsd.persistence
error 23:23:24.385962+0100 kernel Sandbox: Family(1316) deny(1) mach-lookup com.apple.contactsd.persistence
error 23:23:27.389910+0100 kernel Sandbox: Family(1316) deny(1) mach-lookup com.apple.contactsd.persistence
error 23:23:36.408940+0100 kernel Sandbox: Family(1316) deny(1) mach-lookup com.apple.contactsd.persistence
error 23:23:45.419593+0100 kernel Sandbox: Family(1316) deny(1) mach-lookup com.apple.contactsd.persistence
error 23:23:54.432109+0100 kernel Sandbox: Family(1316) deny(1) mach-lookup com.apple.contactsd.persistence
The above is just an except, and it seems that Family, imagent and searchpartyuseragent are trying to access com.apple.contactsd.persistance once per second or so and failing (there are also some attempts to reach com.apple.timed.xpc, but an insignificant amount in comparison to com.apple.contactsd.persistance). This in turn causes Diagnostics Reporter to start, and then end hastily almost every ten seconds.
fault 23:23:05.903908+0100 Diagnostics Reporter Invalid launch.
fault 23:23:16.038017+0100 Diagnostics Reporter Invalid launch.
fault 23:23:26.136348+0100 Diagnostics Reporter Invalid launch.
fault 23:23:36.274543+0100 Diagnostics Reporter Invalid launch.
fault 23:23:46.414546+0100 Diagnostics Reporter Invalid launch.
I have no idea how I did this, but I seemed to have messed up sandbox access rights to contacts for some system services?
Hey! Im new here and currently learning iOS/macOs development (SwiftUI), so...take me easy :) I want to create a simple macOS app to let user set time until computer power off. I found an example with AppleScript and use it on my app, but I found that App won't run with Sandbox enabled, and to deploy app on AppStore it show me that Sandbox must be enabled.
The script I want to use:
'tell application "System Events" to shut down'
I found some examples that add script onAbsolute path, but after I do that, it won't let me to distribute the app, only export to run local.
It is any way to make script running (no matter, if app ask for user permission/admin pass) ?
I recently reset my machine to factory settings to start the year fresh and installed Xcode 15.1 on my Macbook Air M1.
I was trying to run, build, archive a project and ran into a recommended settings pop-up that I unfortunately dismissed.
Now I am not sure how to locate it or trigger it back so I can update it appropriately.
Can someone advise? Thanks in advance!
Is setting "Enable App Sandbox : Yes" required for distributing an app to the App Store?
I'm building my first app, a game, and can only test on my physical device with the Sandbox set to No. I can run it on the emulators with Sandboxing enabled.
I'm still using the free developer account and will be enrolling in the paid account once 2024 arrives.
Electron app builded successfully with electron forge and @electron/osx-sign. But it crash when startup and get crash log below:
Time Awake Since Boot: 320000 seconds
Time Since Wake: 9200 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [95916]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
if I use custom entitlements, it shows:
Time Awake Since Boot: 310000 seconds
Time Since Wake: 8600 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [93221]
Application Specific Information:
dyld: launch, running initializers
/usr/lib/libSystem.B.dylib
Could not set sandbox profile data: Operation not permitted (1)
Application Specific Signatures:
SYSCALL_SET_PROFILE
here is entitlement:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
inherit entitlement:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
what can I do to resolve it?
I'm distributing my app in zip format. But stuck in app update? My app self-detects for the latest version. If yes, then launch other non-appsandbox app that download the latest version, and then replace the old app (in the /Applications directory) with the new one. It works correctly. But once I made the Updater app a Sandbox app, it did not allow me to replace the app. Error: You don’t have permission to save the file “ESPlus” in the folder "Applications.”
I am creating a MacOS app embedding the QuickLook extension in it.
The other day, I uploaded it to App Store Connect and had it reviewed.
But it was rejected due to the following reason.
Your app incorrectly implements sandboxing, or it contains one or more entitlements with invalid values. Please review the included entitlements and sandboxing documentation and resolve this issue before resubmitting a new binary.
com.apple.security.temporary-exception.files.absolute-path.read-only /
This entitlement is also included in my app's meta data on my account page of App Sore Connect. Including it, I can find the following two entitlements related to "temporary-exception" in the meta data.
com.apple.security.temporary-exception.files.absolute-path.read-only: ( "/" )
com.apple.security.temporary-exception.mach-lookup.global-name: ( "com.apple.testmanagerd", "com.apple.dt.testmanagerd.runner", "com.apple.coresymbolicationd" )
To tell the truth, about Sandbox entitlements for QuickLook extension, what I intentionally set on the Xcode project are the next two items only. And actually I have not ever recognized that the entitlements related to "temporary-exception" above are included in my app's bundle.
com.apple.security.app-sandbox: true
com.apple.security.files.user-selected.read-only: true
I think these "temporary-expection" entitlements are essential ones for the QuickLook extension and it looks like that Xcode automatically attached them in the process of creating app's build. If they are forced to be attached by getting the QuickLook extension sandboxed, I don't know what I should do.
Although I explained my thought to the reviewer, but I could not change the situation. Is there no way to get solution besides removing the QuickLook extension from my app ?
I’m trying to implement XPC Rendezvous like Quinn described in many awesome posts on here but I’m now at a stuck point were I just have no idea.
I want to communicate with a Safari extension via XPC and also a helper application which led me to XPC Rendezvous (https://developer.apple.com/forums/thread/715338) because a XPC Service in the Extension is scoped to the container. I then made a Command Line Target and added it like its described here (https://developer.apple.com/documentation/xcode/embedding-a-helper-tool-in-a-sandboxed-app
) and also took the xpc test code and inspiration to set up my launch agent from here (https://developer.apple.com/documentation/servicemanagement/updating_your_app_package_installer_to_use_the_new_service_management_api). This command line tool should do the management for the XPC connections because it’s not in the sandboxed container.
The tool sets up the xpc connection like in the sample code directly and not in a XPC Service added via a Target template. It exposes the Mach Service.
And that looks like its building fine after some fighting but the service just wont start - I saw it trying in console and after running it in Xcode and finally finding the crash report - it brought me there (https://developer.apple.com/forums/thread/706390)
I have Process is not in an inherited sandbox. - and thinking about it, it makes sense because I first thought its just because it ran through Xcode, but its crashing this way also as a LaunchAgent.
I mean it does make sense - there is nothing to inherit because it’s spawned by launchd - and that’s what I want isn’t it - to make the Rendezvous?
Okay I thought now removing com.apple.security.inherit brings it in its own Sandbox (its needs sandboxing) but this also crashes the process because of the sandbox. Also after adding it to the App Group. What am I missing here or what do I want to accomplish? Do I want to inherit the sandbox? I guess not the helper should have its own.
The only difference I see in comparison to SMAppServiceSampleCode is it moves the product in Copy Bundle Resources, and I have a Copy Files Phase with Destination: Executables (Like the other sample code said - and that’s looks “more correct” - and well SMAppServiceSampleCode isn’t sandboxed.
I then tried making a new Command Line Target and just added App Sandbox Capability and tried to run this fresh one - and that also crashes. This makes me think I’m just ****** somewhere but I have read now everything I could find.
I’m happy to provide any Code or crash logs but I dont know what part is really relevant here, It looks like the LaunchAgent gets installed correctly and wants to run but the sandbox is preventing me. The Bundle Identifier and XPC device name of the helper starts with my teamID
(I got that from here https://developer.apple.com/forums/thread/703702)
What could I be doing wrong?
Thanks a lot!
Benjamin
Hi there! I am trying to publish a macOS app on App Store, thus the app must be sandboxed. The app is built with Electron and electron-builder. A tool of the app needs to run a local web server, to do so a java runtime and a .jar file are downloaded during runtime and the server is started using spawn.
In the MAS version of the app, running from TestFlight, I get EPERM error when spawn is called.
Both java's runtime and .jar are downloaded to app's container. I have tried also downloading them to outside the container (by saving them in the directories that are symlinked to outside of it) by I get the same error.
How could I solve that issue?
Context
I'm using the NSFileCoordinator & NSFilePresenter in a sandboxed application to access SQLite database files and their secondary files (e.g. WAL or journal files) as per https://developer.apple.com/documentation/foundation/nsfilepresenter/1415415-primarypresenteditemurl
E.g. something similar to this:
var presenters: [NSFilePresenter] = ["wal", "journal", "shm"].map { ext in
let presenter = SQLiteTempFilePresenter(databaseId: databaseContext.id, sqliteMainFile: url, newExt: ext)
// addFilePresenter needs to be balanced with a `removeFilePresenter`. See SQLiteTempFilePresenter#deinit
NSFileCoordinator.addFilePresenter(presenter)
return presenter
}
That way there will be a NSFilePresenter for each possible secondary SQLite file (e.g. with the main file being foo/bar/database.sqlite there will be presenter for each of the secondary files foo/bar/database.sqlite-shm and foo/bar/database.sqlite-wal)
Using NSFilePresenter to work with SQLite files within the Sandbox environment works as expected.
Desired change
I'd like to expand the usage of NSFileCoordinator to react to changes to the SQLite files that happen outside of the application.
To achieve that I added an additional NSFilePresenter for the main file (e.g. foo/bar/database.sqlite) that has a func presentedItemDidChange() method. That method does get called when I change the corresponding SQLite file (e.g. by using the sqlite3 command line tool).
So far so good. But in WAL mode (https://www.sqlite.org/wal.html), changes to the SQLite file don't immediately change the file itself but get written to the write-ahead-log first (e.g. foo/bar/database.sqlite-wal in this example). Only when the outside connection is closed, will the changes be committed to the main SQLite file itself. At which point the NSFilePresenter#presentedItemDidChange() method will be called. So I also like to be notified when the secondary files change.
Adding a presentedItemDidChange() callback method to the SQLiteTempFilePresenter instances for the secondary files does not seem to work, the method never gets called even though the corresponding secondary files change.
Questions
If I add another instance of the NSFilePresenter for each of the secondary files, the callback presentedItemDidChange() gets called for the secondary files as well. Having two different instance of the NSFilePresenter for a single URL (one for sandboxing purposes, the other for being notified of file changes) seems a bit fishy though. Is that the intended (or at least an acceptable) way of using NSFilePresenter?
The documentation for NSFilePresenter states that "If another process uses a file coordinator for the same file or directory, your presenter objects are similarly notified whenever the other process makes its changes." I do get notified though when using the sqlite3 command line tool which does not use a NSFileCoordinator. Is there any documentation that explains that behaviour? I mean it's great that it seems to work but I'd like to understand why.
We're doing some disaster recovery management / risk management and a point-of-failure for our app is if we lose access to our bundle id.
From my understanding, secure keychain items are scoped to your bundle ID as well as iCloud files stored under the app with 'hidden' scope.
Losing our bundle ID is a scenario we want to eliminate completely from our threat/disaster modelling.
Is this a realistic concern we should have?
I have an app that runs on macOS Monterey.
For various reasons, I have to externally add a sandbox entitlement (externally, as in using codesign, rather than rebuilding it)
After adding the sandbox entitlement, and resigning appropriately, the app crashes on launch with the following error :
ERROR:process_singleton_posix.cc(1186)] Failed to bind() /var/folders/s2/j0z79krx321qg318das1r95_zc0000gn/T/com.funkyapp/S/SingletonSocket
So I assumed I needed to give access to this file.
So I added the following entitlements to the app, via codesign :
<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key> <array> <string>/var</string> <string>/var/folders/s2/j0z79krx321qg318das1r95_zc0000gn/T/com.funkyapp/S/SingletonSocket</string> </array>
and also
<key>com.apple.security.network.client</key> <true/>
<key>com.apple.security.network.server</key> <true/>
Unfortunately, it still crashes on load, with the same error.
Does anyone know why that is? From my perspective, I gave the appropriate entitlements to bind a socket at that path, what am I missing?
Thanks !
Is it possible to create a sandboxed app that uses accessibility permission? And if so, how do I ask the user for that permission in a way that is allowed by the App Store?
Im creating a small menubar app and my current (rejected) solution is to create a pop-up, with link to Security & Privacy > Accessibility and the pop-up asks the user to manually add the app to the list and check the checkbox. This works in sandbox.
Reason for rejection:
"Specifically, your app requires to grant accessibility access, but once we opened the accessibility settings, your app was not listed."
I know it's not listed there and it has to be added manually. But its the only solution I've found to this issue. Is there perhaps any way to add the app there programmatically?
Im a bit confused since I've seen other apps in App Store that work the same way, where you have to add the app to the list manually. Eg. Flycut. :man-shrugging:
I know about this alternative solution, and it's not allowed in sandboxed apps. It also adds the app to the accessibility list automagically:
func getPermission() {
AXIsProcessTrustedWithOptions([kAXTrustedCheckOptionPrompt.takeUnretainedValue():true] as CFDictionary).
}
Does anyone have a solution for this?
Best regards,
Daniel
I've got an app that is sandboxed, and it requires a privileged helper. I've worked through the EBAS sample app with various updates to conform with current systems. After a lot of work, I've got to a point where I'm stumped.
The Python script SMJobBlessUtil.py returns this error, and I don't know what to do to correct it:
<path to helper tool>: tool __TEXT / __info_plist section dump malformed (2)
I've gone over the various settings numerous times. It doesn't fail for the EBAS sample, but does for my app. Looking at the binary, the __info_plist sections look identical apart from identifiers. This is what mine looks like (identifiers deleted):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>***</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>***</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>SMAuthorizedClients</key>
<array>
<string>anchor apple generic and identifier "***" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "***")</string>
</array>
</dict>
</plist>
I must be missing something, but I've run out of ideas on where to find it. Anybody got a pointer?