上个月写了篇《技术的洁癖》比较了一下 Mac OS X 的单文件应用和 installer 两种发布手段,基本上只针对安装和卸载的完全度。不久之后看到某国企发布的一款应用的 installer 居然把 /etc
之下的所有文件权限改成『 777 』,想到单文件应用绝不会有这样的行为,所以写了这篇谈论一下安全问题。
安全是一个复杂的多层面的话题,在讨论普通 Unix 和 Windows 这样的基于 access control list 的 DAC 安全模型时,往往仅仅限于满足一个基本的要求 —— 恶意代码不能修改或者毁坏当前用户之外其他用户的和系统的数据,但是并不要求恶意代码无法修改或者毁坏当前用户自己的数据。在某些高标准的环境中,这个基本要求是远远不够的。但是对于大多数个人应用来说,只要满足这个基本要求,就可以通过系统本身的合理配置建立『沙箱』隔离恶意代码。
这个标准同样可以用来要求应用程序的发布方案:安装和卸载应用程序的过程不能修改或者毁坏当前用户之外其他用户的和系统的数据,但是并不要求恶意代码不修改或者毁坏当前用户本身的数据。
要分析这个要求是否能得到满足,先分解一下安装过程。一般来说,安装应用包括两个动作:
- 把应用程序的可执行文件拷贝到目标机器的硬盘(或其它存储设备)。这个过程可能包括文件的解压缩等操作 [1]。
- 执行一个或者多个『脚本』[2] 来创建或者修改一些配置文件。
简单考虑,如果保证每个用户拥有各自独立的可执行文件拷贝和配置文件,那么只要让安装的整个过程都只在普通用户权限下执行,前面所说的对安全的基本要求即可得到满足。
对今天的系统和大多数应用来说,保证每个用户有各自独立的配置文件不成问题,但是大多数系统都要求应用的可执行文件由所有用户共享。一般情况下,应用的可执行文件都要拷贝到系统文件夹之下。这意味着如果使用 installer ,就必须用系统管理员权限来执行。这就给了 installer 绕过『不能修改或者毁坏当前用户之外的其他用户和系统的数据』这个要求的机会。
有人会考虑把 installer 分解成两部分,分别执行上面的第一步和第二步,而只给第一部分系统管理员权限。可是,对于一个可执行的 installer ,即使名义上分成了两部分,用户也很难限制第一部分做什么,它完全可能毁坏系统数据,或者更糟,把安装的可执行文件的 ACL 设置成可提升权限 [3] ,又或者把所有系统文件的权限改写成『 777 』。这是一个看似可行但是错误的方案,因为最小权限分离仅仅适用于防止可信程序由于 bug 被恶意代码劫持权限,而 installer 在这个情景中是『可疑』的,其行为是用户不能确定的。
真正可行的办法是让用户调用操作系统的命令而非 installer 来执行第一步 [4],因为系统命令本身是可信的(trusted),即使用管理员权限运行系统命令,只要正确输入参数,其行为是用户可以确定的,不会造成危害。
上面这个过程其实就是设计应用发布方案过程中的一个需求迭代,当安全因素纳入考虑之后,迭代的结果把最初的基于 installer 的方案变成了一个类似 Mac OS X 单文件应用的方案:
- 单文件应用的第一步完全依靠 OS X 本身的 Finder 完成。虽然需要管理员权限,但是应用本身,即便是恶意的,也没有机会在这个过程中采取恶意行动。
- 单文件应用的配置文件在应用的第一次运行时生成,只要始终用普通用户运行,恶意程序没有机会毁坏其它用户和系统数据。
从这个对比可以看到,installer 确实给了有技术洁癖的人一个整洁的装饰板,可是饰板之下未必就是优雅。以高度互信作为前提的『整洁』的方案,到了『可疑』环境中可能悄悄的毁坏数据。如果非要坚持其表面的整洁,整个方案也很难通过简单的改动弥补安全方面的问题。
当然,在满足本文涉及的安全需求方面,只有单文件应用拥有优势。而 OS X 本身就存在其它安装方式,而且也在不断引入新的安装方式,比如 Photoshop 的定制 installer 和 Mac App Store。不过本文主要针对的是在不考虑 kernel 的严重 bug 的情况下,限制『可疑』应用危害的方法。而 Photoshop 和 Mac App Store 之类的方案则从其它方面提高了应用的『可信度』。那是另外一个话题了。
注释:
- Mac OS X 的单文件应用不包括这种操作。
- 这里的脚本并非狭义的纯文本解释执行的脚本文件,而是值这种配置操作实质只是一种脚本类的操作。
- 比如 Unix 文件系统的 s 属性,可以让一个可执行文件即使被非管理员用户执行也拥有管理员权限。
- 对于采用特殊的私有格式进行打包或者压缩的应用,这种操作很困难。
发表评论