Sandbox/OS X Rule Set
References
References | |
---|---|
1 |
Apple's Sandbox Guide v1.0 13-09-2011 |
2 |
Sandbox setup in the source: see usage of the variable 'contentSandboxRules' and the call to StartMacSandbox() in Sandbox.mm: |
Glossary
References | |
---|---|
~ |
Refers to the full path to the home directory of the user. On OS X this is /Users/<username>. |
[^/]+ |
This is used in some of the regular expressions. [^/] matches a single character that is not a '/'. [^/]+ Matches 1 or more non-slash characters. |
Notes
- One of the confusing things about the Mac file-system related rules is the redundancy.
The rules use the "(default deny)" directive which means that unless an access is explicitly allowed, it should be denied. Then, interspersed throughout the ruleset we have several filesystem rules to allow read access to specific locations on the system. Later we have a general rule that allows access to anything on the system that is not in ~/Library (i.e., access to ~/Library is blocked with some exceptions) making many of the specific rules redundant. Read/write access to ~ is needed for now (see Deny Filesystem Access for an explanation). Once we can remove read/write access to ~ from the rules, we'll eliminate the redundancy. Lastly we have rules allowing access to specific directories in ~/Library. Bug 1083344 "Tighten rules for Mac OS content process sandbox on 10.9 and 10.10" documents how this came to be -- not allowing access to ~ broke too many things. - An allow rule doesn't bypass OS filesystem permissions that would otherwise block a user's access.
- Because of the redundancy, we could remove most filesystem rules and replace them with rules that equate to (allow everything, but don't allow ~/Library except for a few subdirectories in ~/Library).
- Use of file* in the rules includes all of file-read, file-write, file-read-metadata, and file-write-metadata.
Annotated Rules
Rule | Description |
---|---|
static const char contentSandboxRules[] = | |
link
(version 1) |
References[1] states only version 1 is supported. I tried with version=2 and sandbox_init failed due to "unsupported version". |
(define sandbox-level %d) (define macosMinorVersion %d) (define appPath \"%s\") (define appBinaryPath \"%s\") (define appDir \"%s\") (define appTempDir \"%s\") (define home-path \"%s\")
(if (< sandbox-level 2) (allow file* (require-not (home-subpath \"/Library\"))) ;else (allow file* (require-all (subpath home-path) (require-not (home-subpath \"/Library\")))))
|
These setup some macros to be used later in the policy. See the next row for examples of what they evaulate to on a Nightly build. |
Example output of the above macros after running a Nightly build. Paths abbreviated with "...". (define sandbox-level 1) (define macosMinorVersion 11) (define appPath "/.../NightlyDebug.app/Contents/MacOS/plugin-container.app") (define appBinaryPath "/.../NightlyDebug.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container") (define appDir "/.../NightlyDebug.app/Contents/Resources/browser") (define appTempDir "/Users/<USERNAME>/Library/Caches/TemporaryItems/Temp-{62ac76fa-73fd-8f46-bd2b-12c4d53aa1cc}") (define home-path "/Users/<USERNAME>") | |
; Allow read access to standard system paths. (allow file-read* (require-all (file-mode #o0004) (require-any (subpath "/Library/Filesystems/NetFSPlugins") (subpath "/System") (subpath "/private/var/db/dyld") (subpath "/usr/lib") (subpath "/usr/share")))) |
Allow these directories and any contained directories and files to be read if the file's permission permits any user to read them. |
(allow file-read-metadata (literal "/etc") (literal "/tmp") (literal "/var") (literal "/private/etc/localtime")) |
Allow reading of metadata of these directories. |
; Allow access to standard special files. (allow file-read* (literal "/dev/autofs_nowait") (literal "/dev/random") (literal "/dev/urandom") |
/dev/random, /dev/urandom Used for randomization code. autofs_nowait TBD, probably allows non-blocking I/O to autofs paths (used for network mounts and other pseudo mount points.) |
(allow file-read* file-write-data (literal "/dev/null") (literal "/dev/zero")) |
Wondering if we need write access to these. |
(allow file-read* file-write-data file-ioctl (literal "/dev/dtracehelper")) |
Aids debugging the plugin-container using dtrace. Could be removed, but since root privileges are required to read /dev/dtracehelper this wouldn't be exploitable unless Firefox was run as root or with sudo. |
(allow mach-lookup (global-name "com.apple.appsleep") (global-name "com.apple.bsd.dirhelper") (global-name "com.apple.cfprefsd.agent") (global-name "com.apple.cfprefsd.daemon") (global-name "com.apple.diagnosticd") (global-name "com.apple.espd") (global-name "com.apple.secinitd") (global-name "com.apple.system.DirectoryService.libinfo_v1") (global-name "com.apple.system.logger") (global-name "com.apple.system.notification_center") (global-name "com.apple.system.opendirectoryd.libinfo") (global-name "com.apple.system.opendirectoryd.membership") (global-name "com.apple.trustd") (global-name "com.apple.trustd.agent") (global-name "com.apple.xpc.activity.unmanaged") (global-name "com.apple.xpcd") (local-name "com.apple.cfprefsd.agent")) |
Miscellaneous undocumented services. |
; Used to read hw.ncpu, hw.physicalcpu_max, kern.ostype, and others (allow sysctl-read) |
A subset of the rules originally from /System/Library/Sandbox/Profiles/system.sb which ships with OS X. |
" (begin\n" " (deny default)\n" |
By default, we deny. i.e., for any capability not explicitly allowed here, do not allow it to be used. |
" (debug deny)\n" "\n" |
For any rule that causes an action to be denied, log something in system.log. These log entries are easily viewed using the OS X "Console" application and filtering on "sandbox". |
" (define resolving-literal literal)\n" " (define resolving-subpath subpath)\n" " (define resolving-regex regex)\n" |
Shortcut macros. |
" (define container-path appPath)\n" " (define appdir-path appDir)\n" " (define var-folders-re \"^/private/var/folders/[^/][^/]\")\n" " (define var-folders2-re (string-append var-folders-re \"/[^/]+/[^/]\"))\n" "\n" " (define (home-regex home-relative-regex)\n" " (resolving-regex (string-append \"^\" (regex-quote home-path) home-relative-regex)))\n" " (define (home-subpath home-relative-subpath)\n" " (resolving-subpath (string-append home-path home-relative-subpath)))\n" " (define (home-literal home-relative-literal)\n" " (resolving-literal (string-append home-path home-relative-literal)))\n" "\n" " (define (container-regex container-relative-regex)\n" " (resolving-regex (string-append \"^\" (regex-quote container-path) container-relative-regex)))\n" " (define (container-subpath container-relative-subpath)\n" " (resolving-subpath (string-append container-path container-relative-subpath)))\n" " (define (container-literal container-relative-literal)\n" " (resolving-literal (string-append container-path container-relative-literal)))\n" "\n" " (define (var-folders-regex var-folders-relative-regex)\n" " (resolving-regex (string-append var-folders-re var-folders-relative-regex)))\n" " (define (var-folders2-regex var-folders2-relative-regex)\n" " (resolving-regex (string-append var-folders2-re var-folders2-relative-regex)))\n" "\n" " (define (appdir-regex appdir-relative-regex)\n" " (resolving-regex (string-append \"^\" (regex-quote appdir-path) appdir-relative-regex)))\n" " (define (appdir-subpath appdir-relative-subpath)\n" " (resolving-subpath (string-append appdir-path appdir-relative-subpath)))\n" " (define (appdir-literal appdir-relative-literal)\n" " (resolving-literal (string-append appdir-path appdir-relative-literal)))\n" "\n" |
Text substitution macros for dealing with paths. |
" (define (allow-shared-preferences-read domain)\n" " (begin\n" " (if (defined? `user-preference-read)\n" " (allow user-preference-read (preference-domain domain)))\n" " (allow file-read*\n" " (home-literal (string-append \"/Library/Preferences/\" domain \".plist\"))\n" " (home-regex (string-append \"/Library/Preferences/ByHost/\" (regex-quote domain) \"\\..*\\.plist$\")))\n" " ))\n" "\n" " (define (allow-shared-list domain)\n" " (allow file-read*\n" " (home-regex (string-append \"/Library/Preferences/\" (regex-quote domain)))))\n" "\n" |
Macros for dealing with some form of OS X preferences. TBD. |
" (allow file-read-metadata)\n" |
Allows reading file meta-data for all files/dirs the user has permission to read. |
"\n" " (allow ipc-posix-shm\n" " (ipc-posix-name-regex \"^/tmp/com.apple.csseed:\")\n" " (ipc-posix-name-regex \"^CFPBS:\")\n" " (ipc-posix-name-regex \"^AudioIO\"))\n" |
Access via IPC shared memory to services with names matching these regexes? TBD |
"\n" " (allow file-read-metadata\n" " (literal \"/home\")\n" " (literal \"/net\")\n" " (regex \"^/private/tmp/KSInstallAction\\.\")\n" " (var-folders-regex \"/\")\n" " (home-subpath \"/Library\"))\n" |
Allow reading of file metadata for these directories and files. Appears to be redundant given the above "(allow file-read-metadata)" rule? |
" (allow signal (target self))\n" |
Allow the content process to send a signal to itself. Searched for callers of kill(2) in mozilla-central and didn't find any. |
" (allow job-creation (literal \"/Library/CoreMediaIO/Plug-Ins/DAL\"))\n" |
This might be related to using the camera. |
" (allow iokit-set-properties (iokit-property \"IOAudioControlValue\"))\n" |
Setting sound volume? |
" (allow mach-lookup\n" " (global-name \"com.apple.coreservices.launchservicesd\")\n" " (global-name \"com.apple.coreservices.appleevents\")\n" " (global-name \"com.apple.pasteboard.1\")\n" " (global-name \"com.apple.window_proxies\")\n" " (global-name \"com.apple.windowserver.active\")\n" " (global-name \"com.apple.audio.coreaudiod\")\n" " (global-name \"com.apple.audio.audiohald\")\n" " (global-name \"com.apple.PowerManagement.control\")\n" " (global-name \"com.apple.cmio.VDCAssistant\")\n" " (global-name \"com.apple.SystemConfiguration.configd\")\n" " (global-name \"com.apple.iconservices\")\n" " (global-name \"com.apple.cookied\")\n" " (global-name \"com.apple.printuitool.agent\")\n" " (global-name \"com.apple.printtool.agent\")\n" " (global-name \"com.apple.cache_delete\")\n" " (global-name \"com.apple.pluginkit.pkd\")\n" " (global-name \"com.apple.bird\")\n" " (global-name \"com.apple.ocspd\")\n" " (global-name \"com.apple.cmio.AppleCameraAssistant\")\n" " (global-name \"com.apple.DesktopServicesHelper\"))\n" |
Access to more undocumented OS X facilities. |
" (allow iokit-open\n" " (iokit-user-client-class \"IOHIDParamUserClient\")\n" " (iokit-user-client-class \"IOAudioControlUserClient\")\n" " (iokit-user-client-class \"IOAudioEngineUserClient\")\n" " (iokit-user-client-class \"IGAccelDevice\")\n" " (iokit-user-client-class \"nvDevice\")\n" " (iokit-user-client-class \"nvSharedUserClient\")\n" " (iokit-user-client-class \"nvFermiGLContext\")\n" " (iokit-user-client-class \"IGAccelGLContext\")\n" " (iokit-user-client-class \"IGAccelSharedUserClient\")\n" " (iokit-user-client-class \"IGAccelVideoContextMain\")\n" " (iokit-user-client-class \"IGAccelVideoContextMedia\")\n" " (iokit-user-client-class \"IGAccelVideoContextVEBox\")\n" " (iokit-user-client-class \"RootDomainUserClient\")\n" " (iokit-user-client-class \"IOUSBDeviceUserClientV2\")\n" " (iokit-user-client-class \"IOUSBInterfaceUserClientV2\"))\n" |
Sound like this is for accessing various kernel driver provided functionality. |
"; depending on systems, the 1st, 2nd or both rules are necessary\n" " (allow-shared-preferences-read \"com.apple.HIToolbox\")\n" " (allow file-read-data (literal \"/Library/Preferences/com.apple.HIToolbox.plist\"))\n" |
HIToolbox is Human Interface Toolbox. Sounds related to OS X UI controls. |
" (allow-shared-preferences-read \"com.apple.ATS\")\n" |
Possibly font-related. |
" (allow file-read-data (literal \"/Library/Preferences/.GlobalPreferences.plist\"))\n" |
Contains some details about time zone, city, language, display devices. |
" (allow file-read*\n" " (subpath \"/Library/Fonts\")\n" " (subpath \"/Library/Audio/Plug-Ins\")\n" " (subpath \"/Library/CoreMediaIO/Plug-Ins/DAL\")\n" " (subpath \"/Library/Spelling\")\n" " (literal \"/\")\n" " (literal \"/private/tmp\")\n" " (literal \"/private/var/tmp\")\n" |
Filesystem read access to some system directories. |
" (home-literal \"/.CFUserTextEncoding\")\n" |
Filesystem read access to file ~/.CFUserTextEncoding (stores the user's default text encoding.) |
" (home-literal \"/Library/Preferences/com.apple.DownloadAssessment.plist\")\n" " (home-subpath \"/Library/Colors\")\n" " (home-subpath \"/Library/Fonts\")\n" " (home-subpath \"/Library/FontCollections\")\n" " (home-subpath \"/Library/Keyboard Layouts\")\n" " (home-subpath \"/Library/Input Methods\")\n" " (home-subpath \"/Library/Spelling\")\n" |
Filesystem read access to these ~/Library subdirectories. |
" (subpath appdir-path)\n" |
Read access to part of the application bundle: |
" (literal appPath)\n" " (literal appBinaryPath))\n" |
Read access to plugin-container .app: |
" (allow-shared-list \"org.mozilla.plugincontainer\")\n" |
Might not be needed. On OS X 10.11, no matches for files with this name found under ~/Library/Preferences/. Matches found in ~/Library/Caches though. |
"; the following 2 rules should be removed when microphone and camera access\n" "; are brokered through the content process\n" " (allow device-microphone)\n" " (allow device-camera)\n" |
Camera and mic access. |
"\n" " (allow file* (var-folders2-regex \"/com\\.apple\\.IntlDataCache\\.le$\"))\n" |
Read and write access to /private/var/folders/[^/][^/][^/]+/[^/]com.apple.IntlDataCache.le This file not prevent on my 10.11 system. |
" (allow file-read*\n" " (var-folders2-regex \"/com\\.apple\\.IconServices/\")\n" " (var-folders2-regex \"/[^/]+\\.mozrunner/extensions/[^/]+/chrome/[^/]+/content/[^/]+\\.j(s|ar)$\"))\n" |
Read access to |
" (allow file-write* (var-folders2-regex \"/org\\.chromium\\.[a-zA-Z0-9]*$\"))\n" |
Write access to |
"; Per-user and system-wide Extensions dir\n" " (allow file-read*\n" " (home-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n" " (resolving-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\"))\n" |
See the docs on extensions.autoDisableScopes for more information on these paths. The first path allow access to an Extensions directory that applies to all of a user's profiles. The second is for a system-wide Extensions directory that applies to all users. The setting of extensions.autoDisableScopes controls whether or not these locations are used. |
"; Profile subdirectories\n" " (if (not (zero? hasProfileDir)) (allow file-read*\n" " (profile-subpath \"/extensions\")\n" " (profile-subpath \"/weave\")))\n" |
These allow access to the extensions and weave subdirectories within the current profile. Read and write access to the profile director is blocked (in other rules). Bug 1295700 was filed to address removing access to sensitive weave sync data. |
"; the following rules should be removed when printing and\n" "; opening a file from disk are brokered through the main process\n" " (if (< sandbox-level 2)\n" " (if (not (zero? hasProfileDir))\n" " (allow file*\n" " (require-all\n" " (require-not (home-subpath \"/Library\"))\n" " (require-not (subpath profileDir))))\n" " (allow file*\n" " (require-not (home-subpath \"/Library\"))))\n" " (allow file*\n" " (require-all\n" " (subpath home-path)\n" " (require-not\n" " (home-subpath \"/Library\")))))\n" |
File read and write access for $HOME excluding ~/Library and the current profile directory. We need write access for printing. We need read access to allow user to read files from $HOME. i.e., file:// resources. |
"\n" "; accelerated graphics\n" " (allow-shared-preferences-read \"com.apple.opengl\")\n" " (allow-shared-preferences-read \"com.nvidia.OpenGL\")\n" " (allow mach-lookup\n" " (global-name \"com.apple.cvmsServ\"))\n" " (allow iokit-open\n" " (iokit-connection \"IOAccelerator\")\n" " (iokit-user-client-class \"IOAccelerationUserClient\")\n" " (iokit-user-client-class \"IOSurfaceRootUserClient\")\n" " (iokit-user-client-class \"IOSurfaceSendRight\")\n" " (iokit-user-client-class \"IOFramebufferSharedUserClient\")\n" " (iokit-user-client-class \"AppleSNBFBUserClient\")\n" " (iokit-user-client-class \"AGPMClient\")\n" " (iokit-user-client-class \"AppleGraphicsControlClient\")\n" " (iokit-user-client-class \"AppleGraphicsPolicyClient\"))\n" "\n" "; bug 1153809\n" " (allow iokit-open\n" " (iokit-user-client-class \"NVDVDContextTesla\")\n" " (iokit-user-client-class \"Gen6DVDContext\"))\n" |
Graphics |
"\n" "; bug 1201935\n" " (allow file-read*\n" " (home-subpath \"/Library/Caches/TemporaryItems\"))\n" "\n" |
Read-only access to anything in ~/Library/Caches/TemporaryItems |
"; bug 1237847\n" " (allow file-read*\n" " (home-subpath appTempDir))\n" " (allow file-write*\n" " (home-subpath appTempDir))\n" " )\n" ")\n"; |
Allow full reads and writes to appTempDir which (in this example) is "/Users/<USERNAME>/Library/Caches/TemporaryItems/Temp-{62ac76fa-73fd-8f46-bd2b-12c4d53aa1cc}". The directory is reset each time Firefox starts. |
How security.sandbox.content.level Affects File Access (Planned)
This section is in progress
Release | Content Sandbox Level |
---|---|
Nightly(52) | 2 |
Aurora, Beta, Release | 0 |
Access Type | Meaning |
---|---|
R | Reading access to the file at this path or the directory and possibly all subpaths and directories |
W | Write access to the file at this path or the directory and possibly all subpaths and directories |
read metadata | Reading access to the file metadata only. Applies to this path or directory and possibly all subpaths and |
Blocked at Sandbox Level | Access Type | Are Subpaths Included? | Path |
---|---|---|---|
1 | W | yes | <HOME DIR> |
1 | W | yes | <PROFILE DIR> |
2 | R | yes | <HOME DIR>/Library |
2 | R | yes | <PROFILE DIR> |
3 | R | yes | <PROFILE DIR>/extensions |
3 | R | yes | <PROFILE DIR>/weave |
3 | R | yes | <HOME DIR> and anywhere accessible by user by default |
99 | W | no | /dev/null |
99 | R | no | /dev/null |
99 | W | no | /dev/zero |
99 | R | no | /dev/zero |
99 | W | no | /dev/dtracehelper |
99 | R | no | /dev/dtracehelper |
99 | R | no | /private/var/folders/[^/][^/][^/]+/[^/]com.apple.IntlDataCache.le |
99 | W | no | /private/var/folders/[^/][^/][^/]+/[^/]com.apple.IconServices |
99 | R | no | /private/var/folders/[^/][^/][^/]+/[^/]com.apple.IntlDataCache.le |
99 | R | no | /private/var/folders/[^/][^/][^/]+/[^/]/[^/]+.mozrunner/extensions/[^/]+/chrome/[^/]+/content/[^/]+\\.j(s|ar)$\ |
99 | W | no | /private/var/folders/[^/][^/][^/]+/[^/]org.chromium.[a-Z0-9]* |
99 | W | no | ~/Library/Caches/TemporaryItems/Temp-{UUID} (Content Temp Dir) |
99 | R | no | ~/Library/Caches/TemporaryItems/Temp-{UUID} (Content Temp Dir) |
99 | R | no | /dev/autofs_nowait |
99 | R | no | /dev/random |
99 | R | no | /dev/urandom |
99 | R | no | / |
99 | R | no | /private/tmp |
99 | R | no | /private/var/tmp |
99 | R | no | <HOME DIR>/.CFUserTextEncoding |
99 | R | no | <HOME DIR>/Library/Preferences/com.apple.DownloadAssessment.plist |
99 | R | no | <HOME DIR>/Library/Preferences/.../...plist |
99 | R | yes | <HOME DIR>/Library/Colors |
99 | R | yes | <HOME DIR>/Library/Fonts |
99 | R | yes | <HOME DIR>/Library/FontCollections |
99 | R | yes | <HOME DIR>/Library/Keyboard Layouts |
99 | R | yes | <HOME DIR>/Library/Input Methods |
99 | R | yes | <HOME DIR>/Library/Spelling |
99 | R | yes | /Library/Filesystems/NetFSPlugins |
99 | R | yes | /System |
99 | R | yes | /private/var/db/dyld |
99 | R | yes | /usr/lib |
99 | R | yes | /usr/share |
99 | R | no | /Library/Preferences/com.apple.HIToolbox.plist |
99 | R | no | /Library/Preferences/.GlobalPreferences.plist |
99 | R | yes | /Library/Fonts |
99 | R | yes | /Library/Audio/Plug-Ins |
99 | R | yes | /Library/CoreMediaIO/Plug-Ins/DAL |
99 | R | yes | /Library/Spelling |
99 | R | yes | <INSTALL DIR>/Firefox.app/Contents/Resources/browser |
99 | R | no | <INSTALL DIR>/Firefox.app/Contents/MacOS/plugin-container.app |
99 | R | no | <INSTALL DIR>/Firefox.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container |
99 | R | yes | <HOME DIR>/Library/Application Support/[^/]+/Extensions/[^/]/ |
99 | R | yes | /Library/Application Support/[^/]+/Extensions/[^/]/ |
99 | R | yes | <HOME DIR>/Library/Caches/TemporaryItems |
99 | read metadata | no | /etc |
99 | read metadata | no | /tmp |
99 | read metadata | no | /var |
99 | read metadata | no | /private/etc/localtime |
99 | read metadata | no | * |
99 | read metadata | no | /home |
99 | read metadata | no | /net |
99 | read metadata | no | /private/tmp/KSInstallAction.* |
99 | read metadata | no | /private/var/folders/[^/][^/].* |
99 | read metadata | no | <HOME DIR>/Library |