По не совсем понятным мне причинам, ряд критичных к наличию уязвимость приложений, например широко распространенный браузер Firefix, игнорируют использование встроенной в OS X песочницы. Казалось бы, много какие приложения могут игнорировать песочницу, но никак не те, которые скачивают и так или иначе исполняют произвольный контент из интернета. Возмущаться, конечно, можно долго, а можно просто взять и запустить этот самый Firefox в песочнице. Безопасно, интересно и познавательно
Для начала, какой тип песочницы лучше всего подойдет для интернет-браузера? Я решил остановиться на варианте с белым списком, т.е. приложению запрещено все кроме того, что разрешено. Дальне возникает вопрос как получить список разрешенных действий и тут есть варианты:
- Запустить генератор профайла и выкинуть все лишнее;
- Запускать приложение и отслеживать все, что выводится в консоль с тегом
sandbox .
Вариант с генератором довольно прост. Создаем профайл, который ничего не блокирует а только записывает требуемые права.
(trace "/tmp/trace.sb") ;; (1)
Ну и запускаем Firefox с этим профайлом.
sandbox-simplify /tmp/trace.sb > ./trace.sb #(2)
Результаты трассировки будут записаны в файл
Качество получаемого профайла оставляет желать лучшего. В ряде случаев разрешение дается на группы действий, а не на специфическую операцию, кроме того, дальнейшая поддержка такого профайла довольно затруднительна. Я бы сказал что такой вариант лучше всего подходит для портирования приложения под Sandbox, так как позволяет быстро оценить масштабы проблемы и определиться с порядком действий.
Второй вариант, лично я пошел именно этим путем, более долгий, но уже подходящий для более серьезных целей, чем просто портирование приложения. На выходе у меня получился следующий профайл.
(deny default) ;; (1)
(import "bsd.sb")
(import "system.sb")
(allow process-exec ;; (2)
(regex "^/Applications/Firefox.app"))
(allow file-read* ;; (3)
(literal "/Library/Preferences/\.GlobalPreferences\.plist")
(regex "^/Users/.*/Library/Preferences/org\.mozilla\.firefox\.plist$")
(regex "^/Users/.*/Library/Preferences/com\.apple\.LaunchServices/com\.apple\.launchservices\.secure\.plist$")
(regex "^/Users/.*/Library/Preferences/com\.apple\.universalaccess\.plist$")
(regex "^/Users/.*/Library/Preferences/\.GlobalPreferences\.plist$")
(regex "^/Users/.*/Library/Preferences/ByHost/\.GlobalPreferences\..*\.plist$")
(regex "^/Users/.*/Library/Keyboard Layouts")
(regex "^/Users/.*/Library/Input Methods")
(literal "^/Library/Fonts/")
(literal "/Library/Preferences/com.apple.HIToolbox.plist")
(regex "^/Users/.*/Library/Preferences/com.apple.HIToolbox.plist")
(regex "^/Users/.*/Preferences/com.apple.ATS.plist")
(regex "^/Users/.*/Library/Internet Plug-Ins")
(literal "/Library/Internet Plug-Ins")
(regex "^/Applications/Firefox.app.*"))
(allow file-read* file-write* ;; (4)
(regex "^/private/tmp")
(regex "^/private/var/tmp")
(regex "^/Users/.*/Library/Caches/Firefox")
(regex "^/Users/.*/Library/Application Support/Firefox")
(regex "^/Users/.*/Library/Application Support/Mozilla"))
(allow mach-lookup ;; (5)
(global-name "com.apple.CoreServices.coreservicesd")
(global-name "com.apple.dock.server")
(global-name "com.apple.FontServer")
(global-name "com.apple.PowerManagement.control")
(global-name "com.apple.SystemConfiguration.configd")
(global-name "com.apple.coreservices.launchservicesd")
(global-name "com.apple.pasteboard.1")
(global-name "com.apple.coreservices.quarantine-resolver")
(global-name "com.apple.ocspd")
(global-name "com.apple.networkd")
(global-name "com.apple.cvmsServ")
(global-name "com.apple.tsm.uiserver")
(global-name "com.apple.SystemConfiguration.SCNetworkReachability")
(global-name "com.apple.SystemConfiguration.NetworkInformation")
(global-name "com.apple.distributed_notifications@Uv3")
(global-name "com.apple.coreservices.appleevents")
(global-name "com.apple.window_proxies")
(global-name "com.apple.pbs.fetch_services")
(global-name "com.apple.windowserver.active"))
(allow iokit-open ;; (6)
(iokit-user-client-class "AppleMGPUPowerControlClient")
(iokit-user-client-class "AMDRadeonX4000_AMDAccelDevice")
(iokit-user-client-class "AMDRadeonX4000_AMDAccelSharedUserClient")
(iokit-user-client-class "IOHIDParamUserClient")
(iokit-user-client-class "RootDomainUserClient"))
(allow network-outbound ;; (7)
(remote tcp)
(remote udp)
(remote unix-socket (path-literal "/private/var/run/mDNSResponder")))
(allow system-socket)
(allow ipc-posix-shm)
(allow file-read-metadata)
(allow process-fork) ;; (8)
Профайл получается очень простой и, в основном, очевидный: блокируем все по умолчанию и подключаем разрешения из системных правил
Ряд моментов мне показался довольно странным или неожиданным. Так, доступ на запись не подразумевает доступа на чтение и если хочется что бы Firefox мог не только писать, но и читать файл который пишет, нужно давать разрешение на обе операции
Можно запускать и радоваться!
Лиспоподобный профайл? Круто. Надо попробовать
Это TinyScheme
Спасибо, буду знать.