Mac开发(2)沙盒苹果官方文档

文章目录

Mac开发(2)沙盒苹果官方文档

1. 关于苹果权限文件Entitlements

授权赋予iOS或macOS应用特定的功能或安全权限。

设置权利值,以便启用iCloud、推送通知、Apple Pay和应用沙箱。每个授权都有一个默认值,在大多数情况下,默认值会禁用与授权关联的功能。在设置权限时,通过提供适当的键-值对来覆盖默认值。

  • Cloud授权允许您为您的iOS或macOS应用程序使用iCloud数据存储。
    您可以在Xcode项目中逐个目标地设置iCloud权利值。

  • 即使你的iOS或macOS应用没有执行,推送通知也可以让你的应用提醒用户。
    您可以将推送通知权限值设置为配置开发和分发配置配置文件的一部分。

  • Apple Pay和PassKit授权允许使用Apple Pay进行应用内支付,并允许你的应用从PassKit库中获取通行证。

  • 应用沙箱授权可以让你为macOS应用启用名为沙箱的安全特性(在iOS中,所有应用都是自动沙箱的,所以这些沙箱授权不适用)。

如果恶意代码成功地利用了您的应用程序,通过小心地只启用您需要的资源访问,您可以将潜在的破坏降到最低。您可以在Xcode项目中逐个目标地设置应用沙箱权限值。

您可以使用Xcode目标编辑器的Summary选项卡设置许多权利。其他权利需要编辑目标的权利属性列表文件。最后,一些权限继承自iOS配置配置文件,用于运行该应用程序。

要与授权键关联的值的类型取决于该键。许多授权键采用布尔值。对于Xcode项目中属性列表中定义的权利,布尔权利值为或。一些授权键接受字符串或字符串数组作为值。有关应用于各种授权密钥的值的详细信息,请参阅本文档中的章节。

要使用授权密钥,您必须对应用程序进行编码签名,因为应用程序的授权是内置在其代码签名中的。

1.1 启用iCloud在设备之间共享数据

Xcode的目标编辑器包含两个字段,可以让你为应用启用iCloud文档和键值存储。

1.2 启用推送通知来提醒用户

你可以通过苹果的推送通知服务(APNs)向用户发送推送通知,让用户知道你的应用有他们需要的信息。要在应用程序中接收此类通知,请在开发和分发配置文件中申请适当的权限。

1.3 启用Apple Pay和通行证

你可以接受应用内支付的商品和服务。你也可以在钱包里使用通行证。另外,当靠近NFC或其他射频阅读器工作时,Apple Pay界面可以被抑制,应用中还可以提供支付卡。

1.4 启用应用沙箱,以尽量减少恶意代码的损害

使用Xcode的目标编辑器为macOS项目中的目标打开和配置App Sandbox。

注意:本章描述了特定于应用沙箱macOS实现的属性列表键。它们在iOS中不可用。

在macOS Xcode项目中,通过在目标编辑器的Summary选项卡中启用设置来配置细粒度的安全权限。这些设置依次将布尔值添加到目标的.entitlement属性列表文件中的entitlement键。当您构建项目时,这些值将被合并到目标的代码签名中。

你可以把应用沙箱授权看作两个步骤:

  1. 沙箱是一个目标,它删除了与系统交互的大部分功能
  2. 根据需要,通过配置应用程序沙箱权限,将功能恢复到沙箱目标

在运行时,如果目标需要一个目标没有授权的功能或系统资源,沙箱守护进程(sandboxd)会在控制台记录一条冲突消息。

更多关于应用沙盒的信息,请阅读应用沙盒设计指南

1.5 如果需要,使用应用沙箱临时异常

如果您无法在单一版本中将整个应用程序转换到app Sandbox,您可以使用特殊的临时异常权利。

1.5.1 应用沙箱临时异常授权

注意:本章描述了特定于应用沙箱macOS实现的属性列表键。它们在iOS中不可用。

临时异常授权允许macOS应用执行某些操作,否则应用沙箱不允许。

如果你需要申请一个临时的例外授权,使用苹果的bug报告系统让苹果知道什么是不适合你的。在开发macOS平台时,苹果会考虑功能需求。

注意:如果你申请临时例外权利,请确保遵循App Store Connect网站提供的有关权利的指导。具体来说,在App Store Connect的App Sandbox授权使用信息部分确认授权和相应的问题编号,并解释为什么你的应用需要这个异常。

要请求macOS Xcode项目中的目标的临时异常授权,请使用Xcode属性列表编辑器将其添加到目标的.entitlement属性列表文件中。

为任何临时异常授权提供的值是一个字符串或一个或多个字符串的数组。更多关于在macOS中使用临时异常的信息,请参考应用沙箱设计指南中的应用沙箱设计

1.5.2 苹果事件临时异常

当你采用应用沙箱,你的应用保留能力:

  • 接收苹果事件
  • 将苹果事件发送给自己
  • 响应它收到的苹果事件

但是,在应用沙箱中,你不能将苹果事件发送到其他应用,除非你配置了一个脚本目标授权或者一个苹果事件临时异常授权。

脚本目标授权是请求向提供脚本访问组的应用程序发送苹果事件的首选方式,如应用沙箱授权键所述

当您正在编写的应用程序不提供脚本访问组时,请使用apple-events临时异常授权。这个授权包含一个字符串数组,每个字符串都应该包含你想要向其发送Apple事件的应用程序的bundle标识符。例如,要从应用程序向iPhoto发送苹果事件,你可以传递一个包含单个字符串的数组,该字符串的值为com.apple.iphoto。

scripting-targets和苹果权利并不相互排斥,即使对一个目标应用。例如,如果你的应用程序有最低OS版本比10.8,scripting-targets介绍时,和应用程序脚本Apple Mail应用程序编写消息,你继续使用临时权利(包括后缀修改::10.8),同时也包括scripting-targets权利为10.8及以后版本兼容性,如下显示:

<key>com.apple.security.temporary-exception.apple-events:before:10.8</key>
    <string>com.apple.mail</string>
 
<key>com.apple.security.scripting-targets</key>
<dict>
    <key>com.apple.mail</key>
    <array>
        <string>com.apple.mail.compose</string>
    </array>
</dict>

元素1

1.5.3 音频单元托管临时异常

默认情况下,沙箱应用程序只加载声明自己在沙箱中使用是安全的音频单元插件。在这个临时的例外情况下,当应用程序试图加载一个不安全(或未声明)的插件时,用户会被请求获得许可。

Entitlement keyCapability
com.apple.security.temporary-exception.audio-unit-host允许托管未指定为沙箱安全的音频组件。有关详细信息,请参阅音频组件和应用程序沙箱

1.5.4 全局Mach服务临时异常

在应用沙箱中,全局Mach服务的查找会失败,除非你配置了Mach -lookup.global.name临时异常授权。对于希望启用的每个服务,将该服务作为该授权键的值数组的字符串值添加。

Entitlement keyCapability
com.apple.security.temporary-exception.mach-lookup.global-name支持一个或多个全局Mach服务的查找。

1.5.5 全局Mach服务动态注册临时异常

在应用沙箱,动态注册全球Mach服务失败,除非你配置Mach寄存器。全局名临时例外权利。对于希望启用的每个服务,将该服务作为该授权键的值数组的字符串值添加。

Entitlement keyCapability
com.apple.security.temporary-exception.mach-register.global-name启用动态注册一个或多个全局Mach服务。

1.5.6 文件访问临时异常

使用App Sandbox,您的应用程序只能访问它的容器、应用程序组容器、POSIX世界可读的位置以及文件系统中用户指示要直接使用的位置,比如通过与Open或Save对话框交互。如果您的应用程序需要永久访问其他位置,您可以通过启用这里描述的临时异常授权密钥将其他位置带入沙箱。

对于希望启用访问的每个路径,将该路径指定为相应权限键的值数组的字符串值。每个字符串都必须以斜杠(/)字符开头——无论它代表的是绝对路径还是相对于用户主目录的路径。如果您提供的路径指定的是目录而不是文件,则必须使用斜杠字符结束该路径。

  • 对于主路径临时异常,提供相对于用户主目录的路径;也就是说,相对于~
  • 对于绝对路径临时异常,提供绝对路径;也就是相对于/

当只读权限可以使用时,不要使用读/写权限。

重要提示:不要使用这些临时异常权限(家相关路径或绝对路径)来访问共享首选项文件。相反,应使用共享首选项临时异常授权,如共享首选项域临时异常中所述。

Entitlement keyCapability
com.apple.security.temporary-exception.files.home-relative-path.read-only启用对用户主目录中指定的文件或子目录的只读访问。
com.apple.security.temporary-exception.files.home-relative-path.read-write启用对用户主目录中指定的文件或子目录的读/写访问。
com.apple.security.temporary-exception.files.absolute-path.read-only启用对指定绝对路径上的指定文件或目录的只读访问。
com.apple.security.temporary-exception.files.absolute-path.read-write启用对指定绝对路径上的指定文件或目录的读/写访问。

1.5.7 IOKit用户客户端类临时异常

如果需要授予与IOUserClient的其他子类交互的能力,请使用以下授权

Entitlement keyCapability
com.apple.security.temporary-exception.iokit-user-client-class能够指定附加的IOUserClient子类来打开或设置属性。

1.5.8 共享首选项域临时异常

如果您的应用程序需要对共享首选项域进行只读或读/写访问,请使用以下权限。当只读权限可以使用时,不要使用读/写权限。

Entitlement keyCapability
com.apple.security.temporary-exception.shared-preference.read-only启用对用户主目录中指定首选项域或域的内容的只读访问。
com.apple.security.temporary-exception.shared-preference.read-write启用对用户主目录中指定首选项域或域的内容的读/写访问。

1.6 沙盒设计指南

  • 什么是沙盒:
    应用沙箱是macOS提供的一种访问控制技术,在内核级别执行。如果应用程序受到威胁,它的目的是防止系统和用户数据受到损害。通过Mac应用商店发布的应用必须采用应用沙箱。通过开发者ID在Mac应用商店外签名和分发的应用程序也可以(在大多数情况下应该)使用应用沙箱。

复杂的系统总是会有漏洞,而软件的复杂性只会随着时间的推移而增加。无论您多么小心地采用安全编码实践并防范bug,攻击者只需要通过一次防御就可以成功。虽然应用沙箱不能阻止对您的应用程序的攻击,但它可以最小化一个成功的攻击所造成的伤害。

非沙箱应用程序拥有运行该应用程序的用户的全部权限,并可以访问用户可以访问的任何资源。如果该应用程序或与之链接的任何框架包含安全漏洞,攻击者可能会利用这些漏洞来控制该应用程序,这样,攻击者就可以做用户可以做的任何事情。

为了缓解这个问题,应用沙箱策略有两个方面:

  1. 应用沙箱允许你描述你的应用如何与系统交互。然后,系统授予应用程序完成工作所需的访问权限,仅此而已。
  2. 通过打开和保存对话框、拖放和其他熟悉的用户交互,应用沙箱允许用户透明地授予应用额外的访问权限

沙盒作用

应用沙箱并不是什么灵丹妙药。应用程序仍然可以被破坏,一个被破坏的应用程序仍然可以造成破坏。但是,当一个应用程序被限制在完成其工作所需的最低权限集时,潜在损害的范围是非常有限的

1.6.1 App Sandbox基于一些简单的原则

通过限制访问敏感资源在每个应用的基础上,应用沙箱提供最后一道防御盗窃、腐败、或者删除用户数据,或劫持系统硬件,如果攻击者成功地利用安全漏洞在你的应用程序。例如,一个沙箱应用程序必须显式地声明其意图使用权利使用任何以下资源:

  • Hardware (Camera, Microphone, USB, Printer)
  • Network Connections (Inbound or Outbound)
  • App Data (Calendar, Location, Contacts)
  • User Files (Downloads, Pictures, Music, Movies, User Selected Files)

对项目定义中未明确请求的任何资源的访问在运行时被系统拒绝。例如,如果您正在编写一个素描应用程序,并且您知道您的应用程序将永远不需要访问麦克风,那么您只需不要求访问,并且系统知道拒绝您的应用程序使用它的任何尝试(可能已被破坏)。

另一方面,沙箱应用程序可以访问你请求的特定资源,允许用户以通常的方式执行典型操作(如拖放)来扩展沙箱,并可以自动执行许多被认为安全的附加操作,包括:

  • 从服务菜单调用服务
  • 读取大多数世界可读的系统文件
  • 打开用户选择的文件

App Sandbox的元素包括授权、容器目录、用户决定的权限、特权分离和内核强制。这些功能结合在一起,可以防止应用程序访问系统中超出完成工作所需的部分。

相关章节:App沙箱快速启动App沙箱深入

1.6.1.1 App沙箱快速启动

在这个快速启动的过程中,您将获得一个macOS应用程序并在沙箱中运行。您验证应用程序确实是沙箱的,然后学习如何排除故障并解决一个典型的应用沙箱错误。你使用的应用程序是Xcode,活动监视器,终端和控制台。

1.6.1.1.1 创建Xcode项目

在快速启动中创建的应用程序使用web view,因此使用网络连接。在App Sandbox下,网络连接是不能工作的,除非你特别允许他们-使这成为一个学习沙箱的好例子应用程序。

  • 在Xcode中,为macOS Cocoa应用程序创建一个新的Xcode项目。
  1. 将项目命名为AppSandboxQuickStart。
  2. 如果还没有设置组织名称和标识符,则设置组织名称和标识符。组织标识符是bundle标识符的第一部分,通常使用反向dns格式构造,如About bundle id中所述。因此,如果您的组织名称是Acme,那么您的组织标识符将是com。这将产生一个包标识符com.Acme.AppSandboxQuickStart。
  3. 确保Use storyboard复选框被选中,而其他复选框未被选中。
  • 在项目导航器中,单击Main。故事板文件。
    将出现接口构建器画布。
  • 在对象库(在实用程序区域)中,找到WKWebView对象。
  • 拖动一个WebKit视图到画布上的视图控制器场景中的视图控制器管理的视图上。
  • (可选)要改善web view在运行app中的显示效果,可执行以下步骤:
  1. 拖拽web view上的大小调整控件,以便它完全填充视图控制器的主视图。
  2. 向web view添加约束,以将其顶部、底部、左侧和右侧的边缘固定在主视图上。
  • 添加WebKit框架到应用程序。
  1. 通过在ViewController.h头文件的接口块上面添加以下语句来导入WebKit框架:@import WebKit;
  2. 将WebKit框架链接到Quick Start项目,作为必需的框架。
    注意:如果你正在编译OS X 10.7并且想要在这个应用程序中播放HTML5嵌入视频,你还必须链接到AV基础框架。这在macOS 10.8及以后版本中是不需要的。
  • 在ViewController类中为web view创建并连接一个outlet。在视图控制器的界面(要么在ViewController.h中,要么在ViewController.m中的一个类别中),添加以下内容:@property (weak) IBOutlet WKWebView *webView;

  • 将web view连接到您刚刚创建的应用程序委托出口。

  • 在视图控制器的viewDidLoad方法中添加以下内容:

[self.webView loadRequest:
    [NSURLRequest requestWithURL:
        [NSURL URLWithString: @"http://www.apple.com"]]];

当视图加载时,此方法从计算机的网络连接请求指定的URL,然后将结果发送到web view进行显示。

现在,构建并运行应用程序。

1.6.1.1.2 确认应用程序是沙箱的

窗口打开,但是没有web内容出现。这是因为默认情况下,所有新的Cocoa应用程序都启用了sandboxing,但是你还没有授予访问网络连接的权限。

除了被阻止的行为,有几个具体的迹象表明macOS应用程序是沙箱。

  1. 在Xcode项目导航器中选择项目文件,然后是目标,最后是功能窗格。您应该会看到App Sandbox功能已经打开,但是没有选择任何特定的功能。如果您确实想禁用沙箱,可以通过将开关更改为Off来实现。
  2. 在Finder中,查看~/Library/Containers/文件夹的内容。因为快速启动应用程序是沙箱的,所以现在有一个容器文件夹以你的应用程序命名。该名称包括项目的公司标识符,因此完整的文件夹名称将是,例如,com.Acme.AppSandboxQuickStart。
    当用户第一次运行应用程序时,系统会为给定的用户创建应用程序的容器文件夹。

注意:在macOS 10.8及以后版本中,Finder默认会隐藏/Library文件夹。要查看它,选择去>到文件夹…,并在出现的对话框中进入/Library。

  1. 在活动监视器中,检查系统是否将应用程序识别为沙箱。
  1. 启动活动监视器(可用在/应用程序/实用程序中)。
  2. 在活动监视器中,选择查看>列。
    确保选中了沙箱菜单项。
  3. 在沙箱栏中,确认快速启动应用程序的值为Yes。
    为了更容易在Activity monitor中找到应用程序,在Filter字段中输入快速启动应用程序的名称。
  1. 检查应用程序二进制文件是否沙箱。在终端窗口中,输入以下命令:codesign -dvvv --entitlements :- <executable-path>

其中< executable>是app主可执行二进制文件在app bundle中的完整路径(例如AppSandboxQuickStart.app/Contents/MacOS/AppSandboxQuickStart)。此命令生成的输出包含授权的属性列表,其中包括com.apple.security。应用沙盒设置为真,如果应用是沙箱。

重要提示:以上步骤对于快速启动应用程序已经足够了,但是对于包含嵌入式帮助应用程序、XPC服务或其他工具的应用程序还不够。有关更多信息,请阅读外部工具、XPC服务和特权分离

提示:如果应用程序在你尝试运行它时崩溃了,特别是在接收到一个EXC_BAD_INSTRUCTION信号时,最有可能的原因是你之前运行了一个沙箱应用程序,它有相同的捆绑标识符,但是有不同的代码签名。这种启动时的崩溃是一个应用沙箱安全特性,它可以防止一个应用伪装成另一个应用,从而访问另一个应用的容器。
您将学习如何根据这个安全特性,在App Sandbox和代码签名中设计和构建您的应用程序

1.6.1.1.3 解决一个应用沙盒冲突

如果你的应用尝试做一些应用沙箱不允许的事情,就会发生应用沙箱冲突。例如,您已经在快速入门中看到沙箱应用程序无法从web检索内容。对系统资源访问的细粒度限制是应用沙箱在应用受到恶意代码攻击时提供保护的核心。解决这种违规需要在Xcode中添加与应用所需功能相对应的特定权利。

  1. 退出快速启动程序。

  2. 在目标编辑器的capability选项卡中,在App Sandbox部分中,选择与传出连接(客户机)对应的权限。通过修改. permissions属性列表文件,将所需权限的真实值应用到Xcode项目。

注:网络权限是根据谁建立连接而指定的,而不是数据流的主要方向。在本例中,您需要出站连接功能,因为应用程序正在初始化连接。作为服务器的应用程序需要入站连接权限。

  1. 构建并运行应用程序。预期的网页现在显示在应用程序中。

本章展示了一个简单的示例应用程序如何使用授权来启用应用沙箱和请求资源访问,但这只是一个开始。对于一个真正的应用程序,在你可以发布它之前,你附加了一个代码签名你的应用程序。当您开始访问文件系统时,您将在容器目录中工作。当用户通过拖放等自然交互将文件引入沙箱时,您就创建了安全范围的书签,以随着时间的推移保持对这些文件的持久访问。随着应用程序的复杂性增加,可以引入特权分离来实现更细粒度的资源控制。如果最坏的情况发生,这些技术一起提供了一种控制损害的方法。

1.6.1.1.4
1.6.1.1.5
1.6.1.2 App沙箱深入

您采用App Sandbox的具体步骤是您的App独有的,但是App Sandbox保护用户数据的访问控制机制是一致的:

  • Entitlements.:告诉macOS你的应用程序完成工作所需要的系统资源,仅此而已。
  • Containers. 只访问被认为对应用程序安全的文件和目录。
  • Persistent Resource Access. 保留安全范围的书签在你的应用程序的启动到任何额外的文件,用户已经特别授权你的应用程序访问。
  • Code Signing. 明确地向系统识别你的应用程序,这样其他应用程序就不会伪装成你的。
  • Privilege Separation.将你的应用分成更小的部分,每个部分都有自己的资源特权,如果其中一部分被破坏,就能最大限度地减少损失。
1.6.1.2.1 最后一道防线的需要

你可以通过遵循安全编码指南中推荐的实践来保护你的应用免受恶意软件的攻击。但是,尽管您尽了最大努力构建了一个无坚不摧的屏障——通过避免缓冲区溢出和其他内存损坏、防止用户数据暴露以及消除其他漏洞——但您的应用程序仍可能被恶意代码利用。攻击者只需在你的防御系统或你链接的任何框架和库中找到一个漏洞,就可以控制你的应用程序与系统的交互。

通过让你描述你的应用程序与系统的预期交互,App Sandbox被设计用来直面这种情况。然后系统只授予应用程序完成工作所需的访问权限。如果恶意代码获得了一个正确沙箱应用的控制权,那么它只能访问应用沙箱中的文件和资源

如表2-1所示,要成功采用App沙箱,请使用一种不同于您习惯的心态。

表2-1

1.6.1.2.2 权利和系统资源访问

没有沙箱的应用程序可以访问所有用户可访问的系统资源——包括内置的摄像头和麦克风、网络套接字、打印和大部分文件系统。如果被恶意代码成功攻击,这样的应用程序就会表现得像一个具有广泛潜在危害的敌对代理。

当您为您的应用程序启用App Sandbox时,您删除了除了最小的一组特权之外的所有特权,然后使用授权,有意地一个一个地恢复它们。权限是标识特定功能的键值对,例如打开出站网络套接字的功能。

个特殊的权限-启用应用沙箱-打开应用沙箱。启用sandboxing时,Xcode会创建一个.entitlement属性列表文件,并在项目导航器中显示。

如果你的应用程序需要一个功能,通过使用目标编辑器的Summary标签在你的Xcode项目中添加相应的权限来请求它。如果您不需要某个功能,请注意不要包含相应的权限。

你逐项申请津贴。如果你的应用程序只有一个目标——主应用程序——你只需要为那个目标申请授权。如果将应用程序设计为使用主应用程序和助手(以XPC服务的形式),则需要为每个目标分别请求相应的权利。您将在外部工具、XPC服务和特权分离中了解有关这方面的更多信息。

你可能需要比Xcode目标编辑器更细粒度地控制你的应用程序的权利。例如,您可能会请求一个临时的异常授权,因为App Sandbox不支持您的应用程序所需的功能,例如向尚未提供脚本访问组的应用程序发送苹果事件的能力。要使用临时异常权限,可以使用Xcode属性列表编辑器直接编辑目标的.entitlement属性列表文件。

注意:如果您请求临时例外授权,请确保遵循iTunes Connect网站上提供的有关授权的指导。特别要注意的是,记录一个bug,询问你需要的功能,并使用iTunes Connect中的Review Notes字段来解释为什么你的应用需要这个临时异常。一定要提供错误编号。

macOS应用沙箱权限在权限键参考启用应用沙箱描述。要了解如何在Xcode项目中请求目标的授权,请参见App Sandbox Quick Start

1.6.1.2.3 容器目录和文件系统访问

当您采用App Sandbox时,您的应用程序可以访问以下位置:

  • app容器目录。在第一次启动时,操作系统会创建一个特殊的目录,供应用程序使用(仅供应用程序使用),称为容器。系统上的每个用户在他们的主目录中为你的应用程序获得一个单独的容器;您的应用程序为运行它的用户提供了不受约束的对容器的读/写访问。
  • 应用程序组容器目录。一个沙箱应用程序可以指定一个权限,让它访问一个或多个app group容器目录,每个目录在拥有该权限的所有应用程序之间共享。
  • 指定的文件。当用户显式打开或拖放到应用程序中时,一个沙箱应用程序(具有适当的权限)会自动获得对任意位置文件的访问权。
  • 相关的文件。通过适当的权限,您的应用程序可以访问与用户指定文件同名但扩展名不同的文件。这可用于访问功能相关的文件(如与电影关联的字幕文件)或用于以不同格式保存修改后的文件(如在用户添加图片后将RTF平面文件重新保存为RTFD容器)。
  • 临时目录、命令行工具目录和特定的世界可读的位置。沙箱应用程序可以不同程度地访问其他特定位置的文件。

这些策略将在下面几节中进一步详细说明

1.6.1.2.4 应用沙箱容器目录

app沙箱容器目录具有以下特点:

  • 它位于系统定义的路径中,位于用户的主目录中。在沙箱应用程序中,当应用程序调用NSHomeDirectory函数时返回该路径。
  • 你的应用程序对容器及其子目录有不受限制的读/写访问。
  • macOS路径查找api(在POSIX层之上)指的是特定于应用程序的位置。
  1. 大多数路径查找api引用的是相对于应用程序容器的位置。例如,容器包含一个单独的库目录(由NSLibraryDirectory搜索路径常量指定),仅供应用程序使用,以及单独的应用程序支持和首选项子目录。
  2. 将容器用于支持文件不需要更改代码(从应用程序的沙箱前版本),但可能需要一次性迁移,如将应用程序迁移到沙箱中所述。
  3. 一些路径查找api(在POSIX层之上)引用用户主目录之外的特定于应用程序的位置。例如,在沙箱应用程序中,NSTemporaryDirectory函数提供了一个到用户主目录之外、但特定于您的应用程序并位于沙箱中的某个目录的路径;对当前用户可以不受限制地进行读/写访问。这些寻路api的行为根据App Sandbox进行了适当的调整,不需要修改代码。
  • macOS通过应用程序的代码签名建立并加强应用程序与其容器之间的连接。
  • 容器位于一个隐藏的位置,因此用户不会直接与它交互。具体来说,容器不是用于用户文档的。它是为应用程序使用的文件,以及数据库、缓存和其他特定于应用程序的数据准备的。
    对于一个鞋盒风格的应用程序,在其中你为用户的内容提供唯一的用户界面,这些内容放在容器中,你的应用程序可以完全访问它。

iOS注意:macOS容器与iOS容器不同,因为它不是用于用户文档的。此外,与macOS不同的是,iOS容器包含应用程序本身。
iCloud注:正如在iCloud设计指南中描述的那样,苹果的iCloud技术也使用了“容器”这个名称。iCloud容器和App沙箱容器之间没有功能上的连接。

多亏了代码签名,其他沙箱应用程序都不能访问您的容器,即使它试图通过使用您的bundle identifier来伪装成您的应用程序。但是,你的应用程序的未来版本——如果你使用相同的代码签名和捆绑标识——可以重用你的应用程序的容器。

对于每个用户,当用户第一次运行应用程序时,沙箱应用程序的容器目录会自动创建。因为容器位于用户的主目录中,所以系统上的每个用户都会为应用程序获得他们自己的容器。

1.6.1.2.5 应用程序组容器目录

除了每个应用程序的容器,在macOS 10.7.5和10.8.3以及更高版本中,应用程序可以使用com.apple.security。应用程序组有权请求访问同一个开发团队生产的多个应用程序共用的一个或多个共享容器。权限是一个组标识符字符串数组,每个字符串为应用程序所属的不同组命名。组容器用于非面向用户的内容,如共享缓存或数据库。

注意:属于应用程序组的应用程序还可以共享Mach和POSIX信号量,并与其他组成员一起使用其他IPC机制。有关更多细节,请参阅IPC和POSIX信号量和共享内存

应用程序的沙箱会自动放大,包括应用程序的所有组容器。容器本身存储在~/Library/Group Containers/<application- Group id>中,其中<application- Group id>是组的名称,在权限的组标识符字符串中指定。组标识符必须以开发团队ID开头,后面跟着句号。

从macOS 10.8.3开始,你的应用程序可以通过调用containerURLForSecurityApplicationGroupIdentifier: NSFileManager的方法获得一个组容器的路径。

注意:在macOS 10.9中,调用这个方法会自动创建组容器目录,以及组容器目录中的库/首选项、库/缓存和库/应用程序支持文件夹。
在以前的版本中,尽管group container目录是沙箱的一部分,但目录本身不会自动创建。您的应用程序必须创建这个目录,如清单2-1所示:

清单2-1创建一个app group容器目录:

   NSFileManager *fm = [NSFileManager defaultManager];
    NSString *appGroupName = @"Z123456789.com.example.app-group"; /* For example */
 
    NSURL *groupContainerURL = [fm containerURLForSecurityApplicationGroupIdentifier:appGroupName];
    NSError* theError = nil;
    if (![fm createDirectoryAtURL: groupContainerURL withIntermediateDirectories:YES attributes:nil error:&theError]) {
        // Handle the error.
    }

您应该按照组织其他库文件夹的方式组织此目录的内容,根据需要使用标准文件夹名称(首选项、应用程序支持等)。

有关详细信息,请参见授权键引用向应用程序组添加应用程序

1.6.1.2.6 容器之外的Powerbox和文件系统访问

您的沙箱应用程序可以通过以下三种方式访问其容器外的文件系统位置:

与用户交互以扩展沙箱的macOS安全技术称为Powerbox。Powerbox没有API。当您使用NSOpenPanelNSSavePanel类时,您的应用程序会透明地使用Powerbox。您可以通过使用Xcode设置权限来启用Powerbox,如在权限键引用中启用用户选择的文件访问中所述。

当您从沙箱应用程序中调用打开或保存对话框时,出现的窗口不是由AppKit显示的,而是由Powerbox显示的。当你采用应用沙箱时,使用Powerbox是自动的,它不需要改变你的应用沙箱前版本的代码。

注意:当你采用App Sandbox时,NSOpenPanel和NSSavePanel类有一些重要的行为差异,在App Sandbox的打开和保存对话框行为中有描述。

Powerbox提供的安全优势是它不能被编程操作——具体来说,没有恶意代码使用Powerbox访问文件系统的机制。只有用户通过与通过Powerbox打开和保存对话框进行交互,才能使用这些对话框访问之前建立的沙箱之外的文件系统部分。例如,如果用户保存了一个新文档,Powerbox会扩展沙箱,让应用程序对该文档进行读/写访问。

当应用程序的用户指定他们想使用一个文件或文件夹时,系统会将相关路径添加到应用程序的沙箱中。例如,用户将~/Documents文件夹拖放到应用程序的停靠块上(或者拖放到应用程序的Finder图标上,或者拖放到打开的应用程序窗口中),从而表明他们想使用该文件夹。作为响应,系统使~/Documents文件夹及其内容和子文件夹对您的应用程序可用。

如果用户打开了一个特定的文件,或者保存到一个新的文件,系统将使指定的文件,以及该文件单独对您的应用程序可用。

此外,系统自动允许沙箱应用程序:

  • 连接到系统输入方法
  • 调用用户从“服务”菜单中选择的服务。

有些服务不是沙盒安全的。例如,Finder应用程序的Open服务可能允许一个受影响的应用程序通过编程方式在系统的任何地方打开任意文件,从而逃脱它的沙箱。我们鼓励服务提供商将这些类型的服务标记为受限制的(默认情况下服务是不受限制的),在这种情况下,沙盒应用程序仍然可以使用该服务,但只有在用户得到警告并获得明确的继续使用许可之后。有关更多信息,请参阅服务实现指南

  • 打开用户从“打开最近”菜单中选择的文件
  • 通过用户调用的复制和粘贴方式参与到其他应用程序中
  • 读取文件,世界可读,在某些目录,包括以下目录:
/bin
/sbin
/usr/bin
/usr/lib
/usr/sbin
/usr/share
/System
  • 读取和写入通过调用NSTemporaryDirectory创建的目录中的文件

注意:沙箱应用程序无法访问/tmp目录。使用NSTemporaryDirectory函数获取应用程序临时文件的临时位置。

当用户指定了他们想要使用的文件后,该文件就在应用程序的沙箱中。如果你的应用被恶意代码利用,这个文件就很容易受到攻击:app Sandbox没有提供保护。要为沙箱中的文件提供保护,请遵循安全编码指南中的建议。

默认情况下,用户打开或保存的文件会一直保存在沙箱中,直到应用程序终止,只有在应用程序终止时打开的文件除外。这些文件通过macOS的恢复功能在你的应用下次启动时自动重新打开,并自动添加回你的应用的沙箱。

要以不依赖于Resume的方式提供对位于容器外部的资源的持久访问,请使用安全范围的书签,如在安全范围的书签和持久资源访问中所解释的那样。

相关项目

App Sandbox的相关条目功能允许您的应用访问与用户选择的文件同名但不同扩展名的文件。该特性由两部分组成:应用程序信息中的相关扩展列表。plist文件和代码告诉沙箱你在做什么。

在两种情况下,这是有意义的:

  • 场景1:
    您的应用程序需要能够保存与原始文件不同的扩展名的文件。例如,当您将图像粘贴到TextEdit中的RTF文件并保存它时,TextEdit将文件的扩展名从. RTF更改为.rtfd(并将其变成一个目录)。
    要处理这种情况,必须使用NSFileCoordinator对象来协调对文件的访问。在重命名文件之前,调用itemAtURL:willMoveToURL:方法。重命名文件后,调用itemAtURL:didMoveToURL:方法。

  • 场景2:
    您的应用程序需要能够打开或保存多个同名和不同扩展名的相关文件(例如,自动打开与电影文件同名的字幕文件,或允许SQLite日志文件)。
    为了访问辅助文件,创建一个符合NSFilePresenter协议的类。这个对象应该提供主文件的URL作为它的primaryPresentedItemURL属性,并提供辅助文件的URL作为它的presentedItemURL属性。
    在用户打开主文件后,文件演示器对象应该调用NSFileCoordinator类上的addFilePresenter: class方法来注册自己。

注意:在SQLite日志文件的情况下,从10.8.2开始,如果打开SQLite数据库,日志文件、提前写日志文件和共享内存文件会自动添加到相关项列表中,因此这个步骤是不必要的。

在这两种情况下,都必须对应用程序的信息进行小的更改。plist文件。应用程序应该已经声明了一个文档类型(CFBundleDocumentTypes)数组,该数组声明了应用程序可以打开的文件类型。

对于该数组中的每个文件类型字典,如果该文件类型应该被视为用于打开和保存目的的潜在相关类型,则添加键NSIsRelatedItemType和一个布尔值YES

要了解关于文件演示器和文件协调器的更多信息,请阅读文件系统编程指南

1.6.1.2.7 使用沙箱打开并保存对话框行为
1.6.1.2.8 安全范围的书签和持久资源访问
1.6.1.2.9 应用沙箱和代码签名
1.6.1.2.10 外部工具、XPC服务和特权分离
1.6.1.2.11 IPC和POSIX信号量和共享内存
1.6.1.2.12
1.6.1.2.13

1.6.2 设计你的应用程序与应用沙箱在脑海中

在您了解了这些基础知识之后,根据这种安全技术来查看您的应用程序。首先,确定您的应用程序是否适合沙箱。(大多数应用程序)。然后解决任何API不兼容问题,并确定需要哪些权利。最后,考虑应用特权分离来最大化App Sandbox的防御价值。

相关章节:App沙箱设计

1.6.3 Xcode帮助您将现有的应用程序迁移到应用沙箱

当您采用应用沙箱时,您的应用程序使用的一些文件系统位置是不同的。特别地,您将获得一个容器目录,用于应用程序支持文件、数据库、缓存和除用户文档之外的其他文件。Xcode和macOS支持文件从其遗留位置迁移到您的容器。

相关章节:将应用程序迁移到沙箱

1.6.4 在发布之前,先发布你的应用

当你在你的应用中采用了应用沙箱后,作为你每次发布它的最后一步,仔细检查你是否遵循了最佳实践。

相关章节:应用沙箱清单

1.6.5 如何使用该文档

要安装并运行应用沙箱,请在应用沙箱快速启动中执行本教程。在对你打算发布的应用进行沙盒测试之前,确保你深入了解了应用沙盒。当你准备开始沙箱一个新的应用程序,或转换一个现有的应用程序采用应用沙箱时,请阅读《为应用沙箱设计》。如果你正在为用户提供一个新的沙箱版本的应用程序,而用户已经在运行一个没有沙箱版本的应用程序,请阅读将应用程序迁移到沙箱。最后,在发布你的应用程序之前,通过应用沙盒检查表来验证你是否遵循了应用沙盒的最佳实践

先决条件:在阅读本文档之前,请确保通过阅读Mac App编程指南了解macOS开发的整个过程。

为了补充应用沙箱提供的损害控制,您必须通过在整个应用程序中采用安全编码实践来提供第一道防线。要了解如何操作,请阅读安全概述安全编码指南

采用应用沙箱的一个重要步骤是为你的应用申请授权。有关所有可用授权的详细信息,请参阅授权关键参考

通过实现特权分离,您可以在功能完整的应用程序中增强App Sandbox的优势。您可以使用XPC来实现这一点,XPC是一种实现进程间通信的macOS。要了解使用XPC的详细信息,请阅读守护进程和服务编程指南

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值