Android Permission
摘要
Android系统的安全机制分为内核级和应用程序级两个级别。内核级别的安全机制就是传统的Linux UID/GID机制,应用程序级别的安全机制就是我们通常说的permission机制。本文将从Android的安全机制概述、Permission机制的设计目标、Permission的保护级别、Permission机制的原理、Permission机制的实现、Permission机制存在的问题六方面展示调研结果。
1. Android安全机制概述
Android是一个构造于Linux内核之上的系统,它采用了Linux基于UID/GID建立的SandBox机制,实现了应用程序之间、应用程序与系统之间的相互隔离和保护。
由于有些应用程序需要共享数据或进程,为此,Android系统设计了一种sharedUID机制来打破沙箱的壁垒。在程序安装过程中,系统会验证程序的sharedUID和签名,如果sharedUID和签名与系统已安装的应用程序相同,那么Android系统认定两个应用程序由相同开发者开发,为两个程序分配相同的UID,实现程序之间的数据和进程共享。
但是像通讯录,短信和电话这种非常重要的用户隐私数据,用户并不希望直接提供给其他应用程序使用,而是希望在获得用户许可的前提下访问。因此,Android在原有的基础上进行了扩展,提供了permission机制,它主要是用来对应用程序可以执行的某些具体操作进行权限细分和访问控制。另外,Android为了对某些特定的数据块进行ad-hoc方式的访问,还提供了per-URI permission机制。
2. Permission机制的设计目标
-
通知用户:通过列出应用程序可能执行的所有敏感的操作,让用户更多地意识到安装这个应用存在的潜在风险。这假定用户会阅读在安装时弹出的权限列表,并基于这些信息来作出是否安装应用的决定。
-
降低风险:通过限制应用程序访问Android系统敏感的API接口,来降低应用程序对整个系统带来的伤害(比如病毒)。
3. Permission的保护级别
一个权限主要包含三个方面的信息:权限的名称、属于的权限组、保护级别。一个权限组是指把权限按照功能分成的不同的集合。每一个权限组包含若干具体权限。Android权限保护等级按从低到高的顺序划分为以下四种,不同的保护级别代表了程序要使用此权限时的认证方式:
-
normal:普通权限,优先级最低,需要在应用安装时提示用户授权,否则无法安装,而一旦允许,后面APP在运行过程中将一直拥有该权限。
-
dangerous:危险权限,比如通讯录,短信等,该权限在6.0以下,表现行为与normal无异,但在6.0及以上需要在APP运行过程中动态申请。
-
signature:获取该权限,必须保证请求方和接收方使用同一个签名文件,在安装时默认授权,不会提示用户。该权限一般用于系统内置应用,或者同一个公司的多个APP中。
-
signatureOrSystem:相比signature多了一个条件,当请求方为系统应用时默认拥有该权限,一般用于系统内置应用。
4. Permission机制的原理
Permission(权限许可机制)本质上是一种基于能力的访问控制机制。一个应用程序如果没有对应的Permission,将不能进行相应的操作。Android系统中提供了一系列Permission用以保护系统资源,并以API的形式向应用程序提供资源访问接口。当应用程序需要通过这些API访问系统资源时,必须得到相应的权限许可。
Android的Permission工作场景分为三个层次:权限定义层、权限分配层和访问控制实施层。权限定义层中的Permission只是一种能力标识,没有实际意义;权限分配层中将Permission与系统资源和应用程序绑定,形成了具体的访问控制策略;访问控制实施层根据权限分配层形成的策略进行系统资源的访问控制。
应用程序在安装到Android系统之前,应用程序在安装时需要向系统申请对应的Permission,申请的Permission一般在AndroidManifest.xml文件中声明。
Android系统可读取应用程序的Permission申请,并向用户展示和要求用户检查申请。默认情况是Android系统没有授予应用程序任何权限。经用户检查发现不能接受应用程序的Permission申请,则该程序被拒绝安装。
如果用户确认了应用程序的Permission申请,当程序在实际调用API时,系统根据目标资源的访问权限要求再次检查程序,一旦符合要求,访问请求获得允许。该机制对权限的管理属于静态方式,管理的粒度很粗,在程序安装时,如果应用程序的Permission申请获得用户确认,则程序所有的申请权限都获得许可,用户无法对应用程序的权限申请进行选择性许可。而且,在程序运行过程中无法更改授权策略,如果用户想取消应用程序的某项权限,则必须卸载该应用。
Android还将该机制从系统层扩展到了应用程序层。一个应用程序可以像系统资源一样自主的实施类似的访问控制。对于应用程序,其资源包括:Activity、Service、Broadcast Receiver和 Content Provider四种组件,都可以像系统资源一样,对访问者采用基于Permission的访问控制。在使用系统定义的Permission标示外,应用程序还可以定义自己的Permission标示。
5. Permission机制的实现
应用程序在AndroidManifest.xml文件中使用<usespermission>标签申请Permission。当一个应用程序加载到内存时,应用程序包管理服务PackageManagerService会在其成员域mPackages中维护该程序包的信息。该服务为Android的一个系统服务。包的信息用一个PackageParser.Package类的实例保存,包括了组成程序的组件信息和Permission信息。在PackageParser.Package类的成员域mExtras中包含着应用程序的设定信息,包括程序包的签名和申请的权限。
应用程序组件可以和系统资源一样采用Permission机制进行访问控制,防止自身被滥用。为此,应用程序组件需要定义权限标示,以及在组件中用权限标示指定对访问者的权限能力要求。这些应用程序自主的Permission信息作为组件的固有属性保存在mPackages的相应的组件成员域中。PackageManagerService中保存的应用程序的Permission信息均来自对应用程序的AndroidManifest.xml文件的解析。
可以看出,Android 系统的 Permission机制保证了应用程序的访问能力与其软件包中的声明一致,即其执行过程中的访问能力与用户认可确认的能力是一致的。应用程序不能在运行中动态地修改自己的访问能力。应用程序中的所有组件共享一组访问能力,每个组件不会有自己特殊的访问能力。
对于应用程序自主实施的Permission机制,也采用类似的过程。不同的是,系统服务PackageManagerService在生成程序的动态能力时,还会解析AndroidManifest.xml文件中应用程序自主的Permission标示定义。
6. Permission机制存在的问题
首先,不透明的权限问题。用户在安装应用时,系统会把该应用使用的权限列表以界面的方式弹出告诉用户。但是,为什么用这些权限,用户或许不清楚,也许根本就不了解、不关心,由于用户要使用这个应用所以必须安装,从而造成不必要的损失。
其次,不可分的权限集问题。上面提到,应用程序安装后,系统已经给出了使用的权限列表,权限的使用只限于该列表而不能超出该列表。但问题的关键在于,用户不能选中权限列表中的部分选项,要么全选,要么不选,都是一种绝对的状态,用户只有全选权限才能使用该应用程序,否则只能放弃使用。
最后,研发工作者在研发应用程序的过程中,由于某种原因声明了一些或许根本就没有使用到的权限,那么在安装应用程序时,也会告诉用户,从而增加了系统的负担和一些不安全的因素,用户由于担心安全问题而不敢随意安装该应用程序。
-
张中文, 雷灵光, 王跃武. Android Permission机制的实现与安全分析[J]. 信息网络安全, 2012(8):3-6. ↩
-
袁广翔, 潘娟. Android系统应用权限许可机制研究[J]. 电信网技术, 2013(5):24-27. ↩
-
https://developer.android.com/guide/topics/permissions/overview.html ↩