Best practices for debugging OSX entitlement or sandbox problems? - macos

I have a local development builds of an audio software application, and I'm having problems setting up entitlements so that I can receive audio input (com.apple.security.device.audio-input and/or com.apple.security.device.microphone). This works correctly for "official" builds produced via an IBS pipeline, but never locally.
Based on everything I can see, my local builds are correctly configured - my build is signed and codesign shows the correct entitlements. The app requests other permissions for e.g. disk access. The application appears and is checked in "Security and Privacy" under "Microphone". However: my audio input is silent, and I am not asked for permissions when opening an input device (this is not a code issue: for example, the identical commit hash built on another system, and run on my system work fine). For now, I'm only concerned with my local builds being usable - these are not official / app store builds, or intended for use on other systems than my dev system.
This is not a question about "how to do entitlements", or about this entitlement specifically, but more generally - how do I debug this issue:
Are there other a priori ways to check my entitlements beyond codesign --display --entitlements? Where else should I check that, for a given application / binary, entitlements are set up correctly?
When the application attempts to open an a audio input, and access is denied (presumably) because of entitlements, is this failure logged (syslog etc)?
Are there Apple API's that can provide more detailed error information when an operation fails because of entitlements? Can I log the details of an entitlement failure myself?
I have many builds of the application on my system - debug builds, release builds, branches, old versions etc., but only ever see a single application in e.g. Security and Privacy UI. How can I verify that what I see in the UI is correct for e.g. the particular app package / identifier I'm working with?
Any other debugging tips or workflows would be appreciated.
One note: the build system for this project is Cmake/make/command-line-based rather than Xcode based - all entitlements/signing stuff is being done via Cmake and command line tools (again: this has worked before, and works for some builds), so I would prefer solutions that matched this workflow - Apple's documentation is good, but is usually of the form "do this in Xcode", which is unhelpful here.

Related

How to check if two macOS apps, one code signed and notarized, are otherwise identical?

Imagine following scenario:
Person A without a Mac developer account, e.g. someone building an open source app, wants to have this app properly code signing (and notarized, with stapling).
Person B offers to code sign and notarize the app for person A.
The challenge:
How can Person A make sure that the signed code from B is not otherwise modified?
For instance, can A remove code signature and notarization information from the app again, and then use diff to verify that the original app's contents are identical to B's? If so, which commands accomplish this?
Please also consider the possibility that the app is simply a standalone executable (or, alternatively, the app may contain such executables as helpers), meaning the executable includes the signature instead of having it attached to the bundle in Contents/_CodeSignature.
(Disclaimer: I haven't built anything for macOS or iOS since 2016, so I'm a bit behind - please edit my post for me if I'm half-right - but if this answer is incorrect please let me know in a comment and I'll delete it right-away)
Based on these articles:
https://blog.fleetsmith.com/macos-mojave-app-notarization/
https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution
https://scriptingosx.com/2019/09/notarize-a-command-line-tool/
https://www.publicspace.net/blog/mac/2019/07/26/some-things-i-wish-i-had-know-before-starting-to-automate-mac-developer-id-notarization/
My understanding of the process is that your redistributable executable/app package is not actually modified at all - instead Apple records a hash of the files in the package on their servers. Whenever a macOS user runs your program, macOS sends the hash of the application's files to Apple and Apple responds with the notarization information.
However, you can "staple" a notarization receipt to an redistributable executable - which does modify the package - and this allows other macOS users' computers to quickly verify the notarization without needing to contact Apple's servers (though they may still check for notarization revocation in cases where a signing-certificate was compromised).
How can Person A make sure that the signed code from B is not otherwise modified?
If the receipt isn't stapled to the application package, the hash of both package files should be identical.
For instance, can A remove code signature and notarization information from the app again, and then use diff to verify that the original app's contents are identical to B's? If so, which commands accomplish this?
Not diff, but shasum: http://osxdaily.com/2012/02/05/check-sha1-checksum-in-mac-os-x/
shasum ~/Desktop/DownloadedFile.dmg

MacOS Notarize - Gatekeeper does not recognize notarized app

I have a MacOS app and want to distribute to beta users as DMG file outside AppStore.
I have read some articles about how to notarize an app and follow the steps to successfully notarize the DMG file without any problem.
My development machine runs on MacOS 10.14, and XCode version is 10.1.
However when I try to check the notarized DMG file on another testing machine which runs on MacOS 10.14.5 (by sending the file via AirDrop, or download from my website), I still see the popup from GateKeeper with message "'myApp.dmg' can’t be opened because Apple cannot check it for malicious software." on that machine.
It seems Gatekeeper does not work properly to check notarized DMG file. Is there anybody having the same problem and how to fix that?
Short answer
It could be due to an RPATH referencing a path outside the App bundle. Removing this RPATH would resolve the issue.
Inspecting log files
You can find extra information about the rejection (after trying to launch the blocked app) in the Console.app. Note that you should open the Console.app, before trying to open your blocked app, otherwise not all messages may be logged. You should look for process XprotectService in the logs of your device (i.e. choose your device in the left side bar of the Console.app). If the RPATH is indeed the problem, you should find a record like this:
XprotectService: [com.apple.xprotect:xprotect] File /path/to/your/executable/or/library failed on rPathCmd /rpath/causing/the/problem (rpath resolved to: (path not found), bundleURL: /path/to/your/bundle.app)
Inspecting these log files may give you a key to solve other issues too.
Note that I received the following information from an Apple engineer:
Gatekeeper does not inform users via UI about the specifics of the
error, though it is in the logs for developers to look at. The
notarization process is purely about a detecting malicious software
and does not replicate Gatekeeper enforcement. You still need to get
software notarized and test with Gatekeeper.
We are looking to provide better tooling for developers in the future
to pre-flight some of these common errors.
Contact Apple
If you are not able to solve your issue with the above information, you may want to contact Apple itself using the Feedback Assistant. They do not respond very quickly (~1-2 weeks), but the answers are rather to the point.

How to check if my iPhone app is influenced by xcodeGhost?

One year ago I downloaded my Xcode from a third-party source and I'm afraid that if my app has been influenced by the xcodeGhost. Can somebody tell me how to check it?
You can check wether your copy of Xcode contains malicious software by verifying it's code signature:
codesign -vv /Applications/Xcode.app
The code signature will fail verification if Xcode has been tampered with and it will list the files that are suspect.
More information here
XcodeGhost adds an extra CoreServices.framework at:
Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/Library/Frameworks/
to an infected Xcode.
Don't worry,xcodeGhost was writen early this year.If you download Xcode one year ago,your Xcode is totally fine.
For more informations , you can check on xcodeGhost
To go save you can prevent xCodeGhost anyway with a little script in your project. The first version of xCodeGhost is easy to detect:
You need a file with possible xcodeghost links
You need a script to search for this links in your whole project (with grep)
To read more aboutxcodeghost v1, just look at:
https://possiblemobile.com/2015/11/a-lesson-in-xcode-ghost-third-party-frameworks
For v2 of xcodeghost, its not easy as v1, because the links will be generated on a later point of building of app - therefore the only way to detect this is to check your app network acitivity (e.g. with wireshark). Detecting on everything which is not a usual communication of your app. This gives you the possibility to see which frameworks also will communicate with the internet.
The newest version 2 of xcodeghost, you can read here a little bit more:
http://prog3.com/article/2015-11-11/2826185-a-lesson-in-xcode-ghost-third-party-frameworks
Also important if you really want to protect your app/project: Do every test on real device (even analyizing network connection, therefore just give your device a network connection over your macbook (mobile hotspot), this will give you the permission to check explicitely the network connection of your device). Because some hackers are also adding testscripts on 3rd party framework to detect if its on simulator or device.

Mac App Store app rejected because of accessing file system - 2.30

After developing my first Mac app I've decided to submit it to the Mac App Store but it got rejected. Basically my app uses NSOpenPanel for reading Xcode project file and NSSavePanel for saving file after it finishes it's work.
Reviewer pointed out that app is violating 2.30 rule - Apps that do not comply with the Mac OS X File System documentation will be rejected, but I'm unclear why.
When you look at app's workspace you can see it uses CocoaPods for handling dependencies which shouldn't be a problem. Next it has JBLocalizer.framework which is being linked as an embedded library to JBLocalizerApp. JBLocalizerApp is final target sent to the review.
Here is what reviewer pointed out as a problem:
2.30
The application accesses the following location(s):
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBString.gcda'
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBPostProcessStringsOperation.gcda'
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBOperation.gcda'
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBLoadStringsInFileOperation.gcda'
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBLoadSourceFilesOperation.gcda'
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBLoadRootFilesOperation.gcda'
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBFileController.gcda'
'/Users/josipbernat/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/JBLocalizerApp/IntermediateBuildFilesPath/JBLocalizer.build/Release/JBLocalizer.build/Objects-normal/x86_64/JBFile.gcda'
The majority of developers encountering this issue are opening files
in Read/Write mode instead of Read-Only mode, in which case it should
be changed to Read-Only.
Other common reasons for this issue include:
creating or writing files in the above location(s), which are not valid locations for files to be written as stated in documentation
writing to the above location(s) without using a valid app-id as a container for the written files
Please review the "File-System Usage Requirements for the App Store"
of Submitting to the Mac App Store for the locations apps are allowed
to write and for further guidance.
I'm really not sure how can my app violate access to the library which is being linked to. Any suggestions?
You've got Code Coverage turned on in your project settings.
See QA1514 on how it's turned on, which should help you turn it off.

Core Audio doesn't seem to work when using sandboxing

I've just enabled sandboxing in my OS X application, and now my Core Audio code doesn't work. In particular, when I call AUGraphAddNode, it returns the error invalidComponentID, saying just "The operation couldn't be completed". A number of other Core Audio calls seem to work correctly before that, though.
It doesn't seem to be a direct sandbox violation, as there aren't any messages from sandboxd in Console, but it definitely works when I turn off sandboxing. Anyone know why this would possibly happen? The only thing I can imagine is that maybe it's trying to read files that I don't have access to, although I would think that would give me a sandboxing error.
Update:
To clarify, I've tried enabling every sandbox entitlement and the issue still occurs.
I've also narrowed down the issue somewhat. That call only fails if I try to add a node with the component type kAudioUnitType_MusicDevice and subtype kAudioUnitSubType_DLSSynth.
Update 2:
I've figured out a hacky workaround. If I add a temporary exception entitlement to enable read-write access to the user's entire home directory, the error no longer happens. This is obviously not ideal, so I'm continuing to search for better options. I tried to narrow down the access required by adding entitlements for more specific subdirectories, but that didn't work.
I recently submitted the app I was having this issue with to the app store, and it was rejected for using the temporary exception entitlement mentioned in the last update to my question. I was pointed to this article discussing this exact issue.
It turns out that there's another entitlement that's unfortunately not documented in the standard sandboxing documentation: com.apple.security.temporary-exception.audio-unit-host. This will allow audio units, like the DLSSynth, which require permissions greater than the host environment's sandboxing allows, to run in the host environment, provided that the user grants permission at run time.
I'm not sure how long-term this solution is, given that this entitlement is also categorized as a temporary exception, but according to Apple this is the way to go for now.
If you are using Core Audio for microphone input, don't forget to add this to the sandbox entitlements in both your Target Summary and app entitlements file.
This error can occur in audio unit host apps that have been sandboxed.
On Xcode 11, you can turn off Sandboxing by removing it from the Signing & Capabilities tab:

Resources