Entitlements are used in macOS to grant applications access to perform certain actions on the OS. macOS has thousands of entitlements. For a quick description of entitlements, please see the short and easy-to-understand post by The Eclectic Light Company. In that post, they describe how entitlements, sandboxing, and hardening interrelate. We wanted to understand more about entitlements usage distribution, how they interrelate, and which programs contain given subsets of entitlements. This output stems from an earlier post, where we described using GitHub Copilot to write the code for this project.
Jonathan Levin created the entitlements website which enables users to query entitlements by OS version. It’s a great resource, but we wanted to perform more data exploration. Downloadable below are the SQLite databases we created from base OS images.
The GitHub Copilot-generated code for this project can be found on GitHub. We leverage the lief
executable parsing library vs. jtool2
to avoid shelling out to another process for every file we find.
MachO Entitlements
Entitlements are extracted from MachO executable files. The Code Signature
MachO structure contains the Code Directory
flags and two blobs of interest to us:
Entitlements Blob
Signature Blob
For details about MachO code signatures, code directory and other file structures including entitlements please see the detailed post by The Eskimo!.
We store the entire CodeSignature
segment in the fulldb version of the database in case anyone wanted to explore and extract more from that MachO data structure in the future. For example, extracting details from the certificates.
Entitlements SQLite DB files
macOS 13.1 [entitlements only] [desc db] [full db]
Entitlements: 2654
Executables: 1656
Errors:
1838 - No entitlements magic found
6 - No code signature segment found
macOS 12.1 [entitlements only] [full db] *no descriptions
Entitlements: 2326
Executables: 1528
Errors:
1950 - No entitlements magic found
6 - No code signature segment found
SQL Schemas for DBs
Entitlements only
CREATE TABLE entitlements (executable text, entitlement text, value text);
CREATE TABLE errors (executable text, error text);
CREATE TABLE cd_flags (executable text, flags int, hardened boolean);
...
entitlements
links an executable with an entitlement and the value of the entitlementerrors
received during executable parsingcd_flags
Code Directory flags related to code signatures
DescDB adds descriptions
table which is an OpenAI-generated description of the entitlement.
CREATE TABLE entitlements (executable text, entitlement text, value text);
CREATE TABLE errors (executable text, error text);
CREATE TABLE cd_flags (executable text, flags int, hardened boolean);
CREATE TABLE descriptions (entitlement TEXT PRIMARY KEY, description TEXT);
descriptions
are generated by OpenAI and may not be correct. They’re useful as a reference or starting point for understanding the entitlement.
FullDB adds raw
table which is a binary blog of the entitlements and signature sections of the binaries if more exploration is desired.
CREATE TABLE entitlements (executable text, entitlement text, value text);
CREATE TABLE errors (executable text, error text);
CREATE TABLE cd_flags (executable text, flags int, hardened boolean);
CREATE TABLE raw (executable text, entitlements blob, signature blob);
CREATE TABLE descriptions (entitlement TEXT PRIMARY KEY, description TEXT);
...
raw
contains the raw bytes from the entitlements blob and the signature blog. useful for future processing and connections.
Sample Queries
What programs have a specific entitlement
sqlite> select distinct executable from entitlements where entitlement='com.apple.security.get-task-allow';
/usr/bin/qlmanage
/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/repl_swift
/System/Library/PrivateFrameworks/PreviewsInjection.framework/Versions/A/Resources/XCPreviewAgent.app/Contents/MacOS/XCPreviewAgent
/System/Library/Frameworks/QuickLook.framework/Versions/A/Resources/qlmanage.app/Contents/MacOS/qlmanage
/System/Volumes/Data/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/repl_swift
Entitlements for a specific executable
sqlite> select entitlement from entitlements where executable='/usr/bin/qlmanage';
com.apple.private.dmd.policy
com.apple.private.screen-time
com.apple.security.cs.disable-library-validation
com.apple.security.get-task-allow
com.apple.security.network.client
The most common entitlements on the system vs the most common entitlements for programs in /Applications
sqlite> select entitlement, count(*) from entitlements group by entitlement order by 2 DESC limit 10;
com.apple.private.tcc.allow|554
com.apple.security.app-sandbox|414
com.apple.application-identifier|288
com.apple.security.temporary-exception.mach-lookup.global-name|269
com.apple.security.network.client|261
com.apple.security.exception.mach-lookup.global-name|243
keychain-access-groups|234
com.apple.private.accounts.allaccounts|232
application-identifier|224
com.apple.security.personal-information.addressbook|140
sqlite> select entitlement, count(*) from entitlements where executable like '%/Applications%' group by entitlement order by 2 DESC limit 10;
com.apple.security.app-sandbox|129
com.apple.private.tcc.allow|87
com.apple.security.temporary-exception.mach-lookup.global-name|79
com.apple.security.network.client|69
com.apple.security.application-groups|56
com.apple.application-identifier|55
com.apple.private.accounts.allaccounts|46
com.apple.security.personal-information.addressbook|45
com.apple.security.temporary-exception.files.home-relative-path.read-write|42
com.apple.security.temporary-exception.shared-preference.read-write|42
Quick note…since the databases are generated from base OS images all executables are from Apple. On a system with App Store (or downloadable) apps like Slack, Adobe, Pixelmator, and so on…the top 10 entitlements change… below we see entitlements influenced by Electron Apps:
sqlite> select entitlement, count(*) from entitlements where executable like '/Applications%' group by entitlement order by 2 DESC limit 10;
com.apple.security.cs.allow-unsigned-executable-memory|37
com.apple.security.cs.disable-library-validation|37
com.apple.security.cs.allow-jit|35
com.apple.security.automation.apple-events|21
com.apple.security.cs.allow-dyld-environment-variables|19
com.apple.security.device.audio-input|19
com.apple.security.device.camera|19
com.apple.application-identifier|17
com.apple.security.get-task-allow|14
com.apple.security.iokit-user-client-class|13
Injectable Applications
sqlite> select executable from entitlements where entitlement='com.apple.security.cs.allow-dyld-environment-variables' intersect select executable from entitlements where entitlement='com.apple.security.cs.disable-library-validation';
/System/Volumes/Preboot/Cryptexes/App/System/Applications/Safari.app/Contents/MacOS/SafariForWebKitDevelopment
Again, you’ll find a different story on a real system with 3rd party apps.
Description for an entitlement (must load descdb or fulldb versions)
Reminder these descriptions are generated by OpenAI's ChatGPT so correctness is not guaranteed
sqlite> select description from descriptions where entitlement='com.apple.security.files.user-selected.read-only';
The com.apple.security.files.user-selected.read-only entitlement allows an app to access files that the user has explicitly selected, but only in a read-only mode. This entitlement is intended to provide an extra layer of security and privacy for the user, as it prevents the app from making any changes to the selected files. However, it is important to note that this entitlement does not provide any additional security or privacy protections beyond what the user has already selected.
sqlite> select description from descriptions where entitlement='com.apple.security.cs.allow-unsigned-executable-memory';
The com.apple.security.cs.allow-unsigned-executable-memory entitlement allows apps to execute code from memory that has not been signed by Apple. This can be a security risk, as unsigned code can be malicious and can be used to bypass security measures. Additionally, this entitlement can be used to bypass privacy protections, as it can be used to execute code that is not visible to the user.
sqlite> select description from descriptions where entitlement='com.apple.security.cs.allow-dyld-environment-variables';
The com.apple.security.cs.allow-dyld-environment-variables entitlement allows apps to set environment variables for the dynamic linker (dyld). This can be used to control the behavior of the dynamic linker, such as which libraries are loaded and which symbols are resolved. This can be used to bypass security checks, so it is important to be aware of the potential security and privacy implications of granting this entitlement.