Android系统安全

article/2025/6/14 15:44:40

微信公众号:计算机与网络安全

安全机制

Android是一种基于Linux的、自由的、开源的操作系统。它主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟开发。Android系统架构可以分为4层结构,由上至下分别是应用程序层、应用程序框架层、系统运行库层以及内核层,如图1所示。

图1 Android系统结构

Android应用层允许开发者无须修改底层代码就能对设备的功能进行拓展,Android的应用程序框架层为开发者提供了大量的API来访问Android的设备。

Android 应用和Android 框架都是用 Java 语言开发的,并运行在 DalvikVM 中运行。DalvikVM的作用主要就是为操作系统底层提供一个高效的抽象层。DalvikVM是一种基于寄存器的虚拟机,能够解释执行Dalvik可执行格式DEX的字节码,Android 应用和Android 框架都是用 Java 语言开发的,并运行在 DalvikVM 中运行。DalvikVM的作用主要就是为操作系统底层提供一个高效的抽象层。DalvikVM是一种基于寄存器的虚拟机,能够解释执行Dalvik可执行格式DEX的字节码,

Android 将安全设计贯穿系统架构的各个层面,覆盖系统内核、虚拟机、应用程序框架层以及应用层各个环节,力求在开放的同时,也能保护用户的数据、应用程序和设备安全。

1. Android进程沙箱隔离机制

进程沙箱隔离机制,使Android应用程序在安装时被赋予独特的用户标识(UID),并永久保持。应用程序及其运行的Dalvik虚拟机运行在独立的Linux进程空间,与其他应用程序完全隔离,如图2所示。

图2 Android进程沙箱隔离机制

在特殊情况下,进程间还可以存在相互信任关系。如源自同一开发者或同一开发机构的应用程序,通过Android提供的共享UID(Shared UserId)机制,使具备信任关系的应用程序可以运行在同一进程空间。

2. 应用程序签名机制

规定 APK 文件必须被开发者进行数字签名,以便标识应用程序作者和在应用程序之间的信任关系。在安装应用程序APK时,系统安装程序首先检查APK是否被签名,有签名才能安装。当应用程序升级时,需要检查新版应用的数字签名与已安装的应用程序的签名是否相同,否则,会被当作一个新的应用程序。Android 开发者有可能把安装包命名为相同的名字,通过不同的签名可以把它们区分开来,也保证签名不同的安装包不被替换,同时防止恶意软件替换安装的应用。

3. 权限声明机制

要想在对象上进行操作,就需要把权限和此对象的操作进行绑定。不同级别要求应用程序行使权限的认证方式也不一样,Normal级申请就可以使用,Dangerous级需要安装时由用户确认,Signature和SignatureOrSystem级则必须是系统用户才可用。

4. 进程通信机制

基于共享内存的 Binder 实现,提供轻量级的远程进程调用(RPC)。通过接口描述语言(AIDL)定义接口与交换数据的类型,确保进程间通信的数据不会溢出越界,如图3所示。

图3 进程通信机制

5. 内存管理机制

基于Linux的低内存管理机制,设计实现了独特的LMK,将进程重要性分级、分组,当内存不足时,自动清理级别进程所占用的内存空间。同时,引入的 Ashmem 内存机制,使Android具备清理不再使用共享内存区域的能力。

正是因为Android采用多层架构,在保护信息安全的同时,也保证开放平台的灵活性。

Root

在Android设备上获得超级用户权限的过程通常叫作Root,因为超级用户在任何一类的Unix系统中都被叫作Root,拥有所有的文件与程序的权限,能对操作系统进行完全控制。一般情况下,手机厂商出于安全考虑会关闭手机的Root权限,手机系统是运行在普通用户权限下的,用户是无法操作系统中的文件与数据的。

1. Root的作用

(1)卸载系统自带软件

手机出厂时会预装一些软件,这些软件通常无法卸载,必须Root后获取手机的最高权限才可以卸载。

(2)安装一些特殊的软件

有些安卓软件必须Root拥有系统最高权限后才可以安装。

(3)启用或禁用自启动程序

通过Root获取最高权限,可以设置启用或禁用某些自启动程序,即设置某些程序是否随系统一起启动。

(4)打游戏刷高分

有些游戏爱好者通过Root刷分在游戏中快速升级拿高分。

(5)好奇

有些用户纯粹出于好奇去Root手机。当然还有其他的原因,如享受Root成功后的那种喜悦感等。

2. Root的危害

Root 之后虽然可以享受很多便利,但是要意识到 Root 设备将会损害设备的安全性。所有的用户数据都将暴露给被授予Root权限的应用。当您的设备丢失后,其他人就能从中提前数据。带来较大的危害。

(1)硬件危害

手机Root一般情况下不会对硬件造成危害。但Root后可能会导致一些数据出错或丢失,如改变充电电流或照明功率等,从而烧坏手机的元器件。

(2)系统危害

手机Root后,因为一些系统数据的丢失或出错,可能会出现一些系统问题,如手机无法开机、不停地重启无法进入桌面、触屏失灵、Wi-Fi或蓝牙失效等意想不到的系统故障。

(3)软件危害

手机Root后,可能还会造成一些软件无法正常使用。例如除充电缓慢、待机缩短、发热等故障外,照相功能也出现了异常,照相时无法正常预览画面,拍的照片发暗。

(4)信息泄露风险

手机Root后,给用户使用手机带来了较大的自主权,但同时也给恶意软件打开了方便之门。恶意软件可以比平常更容易侵入到手机,并潜伏在用户的手机伺机而动。当用户登录支付宝、淘宝、手机银行或其他账户时,某个人信息可能就会被人窃取,甚至个人财产也存在被人盗取的风险。

(5)影响保修

目前各大手机厂商对于手机Root后有3种售后处理政策。

第一种:手机Root后,不再享有保修的权利,且刷回原系统需收费。

第二种:手机Root后,若IMEI号丢失,不再享有保修的权利,且刷回原系统需收费;若IMEI号丢失,三包期内可继续享有保修的权利,但刷回原系统需收费。

第三种:手机Root后,三包期内继续享有保修的权利,刷回原系统也不收费。

绝大部分手机厂商执行的是第二种售后政策,只有极少数的手机厂商执行的第一种或第三种售后政策。所以如果Root失败或出现故障时,需要去进行售后处理,消费者都一般需要付出付费的代价。即便少数厂商刷机不收费,也可继续保修,若Root失败或出现异常,也会浪费消费者很多时间和精力,而且要接受手机暂时无法正常使用带来的不便和麻烦。

3. Root的原理

Android获取Root其实和Linux切换Root用户是一样的。在Linux下,只要执行su或sudo,输入Root的密码就能获取Root的权限了,其实就是将uid和gid设置为0。在Android5.0之前没有多用户切换,对su也没有密码验证,也没有sudo命令,所以很多Rom都去掉了su命令。

其实在Android系统中,获得了Root比没有获得Root的系统多了两个东西,一个是su二进制文件,一个是superuser.apk,su是用来获得Root权限的命令,superuser.apk是一个管理工具,用来对Root权限进行管理和安全提示。

当某些程序执行su指令想取得系统最高权限的时候,Superuser就会自动启动,拦截该动作并做出询问,当用户认为该程序可以安全使用的时候,就选择允许,否则,可以禁止该程序继续取得最高权限。Root的过程其实就是把su文件放到/system/bin/Superuser.apk放到system/app下面,还需要设置/system/bin/su可以让任意用户可运行,有set uid和set gid的权限。

即要在Android机器上运行以下命令。

adb shell chmod 4755/system/bin/su

下面简单介绍一下su文件的源码,如下。

int main(int argc,char**argv)

{

struct passwd*pw;

int uid,gid,myuid;

/*Until we have something better,only root and the shell can use su.*/

myuid=getuid;

if(myuid!=AID_ROOT&&myuid!=AID_SHELL){

fprintf(stderr,"su:uid %d not allowed to su\n",myuid);

return 1;

}

if(argc<2){

uid=gid=0;

}else{

pw=getpwnam(argv[1]);

if(pw==0){

uid=gid=atoi(argv[1]);

}else{

uid=pw->pw_uid;

gid=pw->pw_gid;

}

}

if(setgid(gid)||setuid(uid)){

fprintf(stderr,"su:permission denied\n");

return 1;

}

/*User specified command for exec.*/

if(argc==3){

if(execlp(argv[2],argv[2],NULL)<0){

fprintf(stderr,"su:exec failed for %s Error:%s\n",argv[2],

strerror(errno));

return-errno;

}

}else if(argc>3){

/*Copy the rest of the args frommain.*/

char*exec_args[argc-1];

memset(exec_args,0,sizeof(exec_args));

memcpy(exec_args,&argv[2],sizeof(exec_args));

if(execvp(argv[2],exec_args)<0){

fprintf(stderr,"su:exec failed for %s Error:%s\n",argv[2],

strerror(errno));

return-errno;

}

}

/*Default exec shell.*/

execlp("/system/bin/sh","sh",NULL);

fprintf(stderr,"su:exec failed\n");

return 1;

}

4. Root的思路

-rwxr-xr-x:r代表该文件可读,w代表可写,x代表可执行,-代表没有该权限。第一个rwx代表文件所有者的权限,第二个rwx代表和所有者同组人的权限,第三个rwx代表其他用户对该文件的权限。但下面这个文件就比较特殊。

rws。它的执行权限标识位是一个 s,s 代表当任何一个用户执行该文件的时候都拥有文件所有者的权限,这文件的所有者是Root,简单来说就是不管谁执行这个文件,他执行的时候都是以Root身份执行的。

也就说即使不是 Root 也有可能以 Root 身份来执行程序,那么就把一个所有者是 Root的su程序权限标识位置成-rwsr-xr-x,不管谁执行它,都是Root身份执行,su就可以顺利执行了,执行成功之后就是Root身份了。

所以,需要把一个所有者是Root的su拷贝到Android手机上,并且把su的权限标识位置成-rwsr-xr-x,就成功Root了一个手机。代码如下。

cp/data/tmp/su/system/bin/#copy su 到/system/分区

chown root:root su #su的所有者置成root

chmod 4775/system/bin/su #把su置成-rwsr-xr-x

但是每一行代码都要Root权限才能执行成功,就是说只有在有Root权限的情况下才能执行上面3行代码,而这3行代码就是为了获得Root权限的,这是一个逻辑闭环,正常情况下是无法实现的。

目前有以下两种思路。

找到一个已经有Root权限的进程来完成上述的命令,一般就是利用系统漏洞提升权限到Root,init进程启动的服务进程,如adbd、rild、mtpd、vold都是有Root权限的。比较经典的是RageAgainstTheCage漏洞,通过adbd启动时候自动降级Shell权限失败,adbd仍然运行在Root权限下面,再用adb连接设备,adb就运行在了Root权限下。

另一个就是通过系统之外植入,如通过Recovery刷机的形式刷入su。

5. Root的分类

可以把Root分成临时性Root与永久性Root。一直保留Root权限有安全隐患,不Root又不能获得一些个性化的体验。所以就提出了临时性Root,不需要的时候再把系统还原回去。

(1)临时性Root

临时性Root实质就是通过一系列操作让系统在短时间内获取Root权限,不需要的时候又将系统恢复到非Root状态下,一般操作方式是判断设备有无重新启动,如果设备重新启动了,则还原用户的ID级别到非Root级别,以取消当前用户的临时Root权限。一方面避免多次弹出授权提醒的问题,造成不好的用户体验,另一方面,Root权限自动消失相对比较安全。有些应用程序只希望自己获得Root权限,很多时候连su和Superuser都没有植入到系统中,这样在自己进程结束的时候就能释放掉Root权限,更加安全。

(2)永久性Root

重启之后不清空Root权限,保持系统的Root状态。通过superuser.apk应用来给出用户提示,以判断何时需要进行Root。

设备一旦被Root,任何应用程序都可以调用su命令来执行Root权限,这样设备是很不安全的,所以需要superuser来完成以下几个工作来保证设备的安全。

Su文件是否被替换修改,建立白名单,只允许特定的应用来使用Root权限,应用程序调用su命令的时候,向用户弹出Root申请界面,如图1所示。

图1 Root申请

系统原生的su对于所有的应用程序是平等的,所以原生的su是无法保证su的安全的,Superuser必须安装入自定义的su,以及能够保证自身su不被替换的Deamon进程。应用请求Root权限的时候,自定义的su则会通知Superuser。由Superuser来进行白名单存储于Root权限授予提示,让用户选择是否给予该应用Root权限。而su与Superuser之间的通信是靠一个阻塞的Socket来完成的。

具体的操作流程如图2所示。

图2 申请Root流程

权限攻击

1. Android权限

相比于Apple,Microsoft严格控制生态系统,只允许通过官方应用商店安装应用,Android的开放就意味着,Google需要向用户提供一系列用于为自己负责的流程和工具。所以在安装应用前,Android总是要事无巨细地告诉您,App需要什么权限。

Android权限指Android中的一系列“Android.Permission.*”对象。Google在Android框架内把各种对象(包括设备上的各类数据、传感器、拨打电话、发送信息、控制别的应用程序等)的访问权限进行了详细划分,列出了约100条"Android.Permission"。应用程序在运行前必须向Android系统声明它将会用到的权限,否则Android将会拒绝该应用程序访问通过该"Permission"许可的内容。

例如,某输入法提供了一个智能通讯录的功能,用户可以在输入联系人拼音的前几个字符或首字母后,输入法就能自动呈现相关联系人的名字。为了实现这个功能,输入法必须声明它需要读取手机中联系人的能力,也就是在相关代码中加上声明"android.permission.READ_CONTACTS"对象。

2. Android权限分类

由于基于Linux内核,Android系统中的权限分为以下3类。

(1)Android手机所有者权限

这个和厂商相关,可以理解为系统权限。

(2)Android Root权限

类似于Linux,这是Android系统中的最高权限。如果拥有该权限,就可以对Android系统中的任何文件、数据、资源进行任意操作。所谓“越狱”,就是令用户获得最高的Root权限。

(3)Android应用程序权限

该权限在AndroidManifest文件中由程序开发者声明,在程序安装时由用户授权,共有4类不同的权限保护级别(Protection Level)。

我们经常在AndroidManifest中使用权限,如果我们想让应用程序可以发短信,那么应该使用如下命令。

<uses-permission android:name="android.permission.SEND_SMS"/>

其权限的定义是在frameworks/base/core/res/AndroidManifest.xml中,如下。

<permission android:name=”android.permission.SEND_SMS” android:permissionGroup=”android.permissiongroup.COST_MONEY” android:protectionLeve=”dangerous” android:label=”@string/permlab_ sendSms”android:deion=”@string/permdesc_sendSms”/>

这个XML可以认为是系统APK使用的AndroidManifest.xml,该APK使用系统的私钥进行签名。

下面分别简单介绍下各个标签的含义。

android:name:权限的名字,uses-permisson使用的。

android:permissionGroup:权限的分类,在提示用户安装时会把某些功能差不多的权限放到一类。

android:protectionLevel:分为Normal、Dangerous、Signature、SignatureOrSystem。

android:label:提示给用户的权限名。

android:deion:提示给用户的权限描述。

其中,android:protectionLevel各个属性说明如下。

① Normal

风险较低的权限,任何应用都可以申请,在安装应用时,不会直接提示给用户,单击全部才会展示。

② Dangerous

风险较高的权限,任何应用都可以申请,安装时需要用户确认才能使用。

③ Signature

仅当申请该权限的应用程序与声明该权限的程序使用相同的签名时,才赋予该权限。

④ SignatureOrSystem

仅当申请该权限的应用程序位于相同的Android系统镜像中,或申请该权限的应用程序与声明该权限的程序使用相同的签名时,才赋予该权限。

3. Android权限处理

Android的策略如下。

(1)文件和设备访问,使用Linux的权限访问控制

部分权限声明之后,应用程序启动的时候,AMS会从PKMS那里获得该应用进程的uid、gid和组id信息,然后通过Zygote来创建一个指定id的进程。获得指定组id的进程,也会获得部分文件的访问权限,如声明 android.permission.WRITE_EXTERNAL_STORAGE 来访问 SDcard 会被赋予 sdcard_rw 的组 id。权限所对应的组 id 在 frameworks/base/data/etc/platform.xml当中。

特别注意:内核检查 id 的顺序是 uid 然后再到 gid和组 id,所以,当声明 android.permission.WRITE_EXTERNAL_STORAGE的同时,声明shareUserId为system,是没有读写SDcard权限的。

(2)Android接口调用控制

首先是 Root 用户和System 用户拥有所有的接口调用权限,然后对于其他用户使用Context的这几个函数来实现,如下。

Context.checkCallingOrSelfPermission(String);

Context.checkCallingOrSelfUriPermission(Uri,int);

Context.checkCallingPermission(Permission);

Context.checkCallingUriPermission(Uri,int);

Context.checkPermission(String,int,int);

Context.checkUriPermission(Uri,int,int,int);

Context.checkUriPermission(Uri,String,String,int,int,int);

Context.enforceCallingOrSelfPermission(String,String);

Context.enforceCallingOrSelfUriPermission(Uri,int,String);

Context.enforceCallingPermission(String,String);

Context.enforceCallingUriPermission(String,String);

Context.enforcePermission(String,int,int,String);

Context.enforceUriPermission(Uri,int,int,int,String);

Context.enforceUriPermission(Uri,String,String,int,int,int,String);

其中,以check开头的,只做检查,以enforce开头的,不单检查,没有权限的还会抛出异常。

这几个函数最后会调用到PKMS的checkUidPermission,该函数通过对比应用权限信息来判断该应用是否获得权限。

(3)Android权限等级

划分为Normal、Dangerous、Signature、SignatureOrSystem、System和Development,其中,Signature需要签名才能赋予权限,SignatureOrSystem需要签名或系统级应用(放置在/system/app目录下)才能赋予权限,SignatureOrSystem需要签名或系统级应用(放置在/system/app 目录下)才能赋予权限,系统权限的描述在 frameworks/base/core/res/AndroidManifest.xml当中。

如果需要在系统中增加一个权限,则将按照下列步骤进行。

① 确定权限属于文件访问控制,还是接口调用控制。

② 在frameworks/base/core/res/AndroidManifest.xml中增加权限描述。

③ 如果是文件访问控制,那就在frameworks/base/data/etc/platform.xml为权限依附指定的组id。

④ 如果是接口调用控制,那就在接口调用里面,加入上述Context检查权限的函数。

4. Android权限危害

Android 应用程序权限所造成的危害主要是由该 Android 应用程序拥有的权限超过其本身所需要的所造成的。

该应用程序在安装时就直接获得了Root权限,这就意味着该应用程序有一把万能钥匙,可以在手机上为所欲为,不仅可以获取手机使用者所有的个人信息,进行扣费、发送消息等操作,还能直接对手机系统本身进行攻击,造成系统不稳定、直接关机、软件闪退或反应慢等,甚至有可能造成手机本身硬件问题,如充电缓慢、待机缩短、发热发烫等。

应用程序在安装时所要求的权限不合理,超过本身所需,很多应用程序会在安装的时候或多或少地多申明一些权限,一方面为该应用程序本身后续版本迭代做准备,另一方面也为了该应用程序能更好地运行。但是,这样会导致权限供大于求,从而造成不必要的麻烦。如一些应用程序习惯性地申明了获取精确地理位置、自动连接网络、绑定用户设备、使用蓝牙、通话权限、拍照权限、底层访问权限等,将对用户的个人隐私及个人财产造成巨大危害获风险。

一些应用程序设置了自动更新版本迭代,当有攻击者仿照该应用程序签名伪造了一个新版本的应用程序时,手机自动更新后将直接被该应用程序攻击。

串权限攻击的主要思想是一个程序A有某个特定的执行权限,一个程序B没有这个权限,但是B可以利用A的权限来执行这个权限。

5. Android权限思考

Android是开放型的系统,因此,需要开发者和使用者双方对Android权限安全进行维护和防护。

对于开发者而言,在开发应用程序的时候实事求是地申明所需权限,并减少外界应用程序对该应用程序的非法调用和访问。

对于使用者而言,需要学会判断应用权限要求的合理性。一款应用应该根据自身提供的功能来要求合理的权限,因此,用户可以根据该应用的功能来简单判定其所要求的权限是否合理。如一款小游戏如果需要获取手机浏览器历史记录、手机联系人资料和本机号码等个人隐私信息,那么它对权限的要求是不合理的,而且很有可能存在短信扣费风险。

组件安全

Android组件包括Activity、BroadcastReceiver、Service和ContentProvider。

1. Activity安全

Activity类型和使用方式决定了其风险和防御方式,Activity分类如表1所示。

表1 Activity分类

Android中提供了Intent机制来协助应用间的交互与通信,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的 Activity/Service 之间的交互。因此,Intent 在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。在SDK中给出了Intent作用的表现形式如下。

1)通过Context.startActivityorActivity.startActivityForResult,启动一个Activity。

2)通过Context.startService启动一个服务,或通过Context.bindService和后台服务交互。

3)通过广播方法(如Context.sendBroadcast、Context.sendOrderedBroadcast,Context.sendStickyBroadcast)发给BroadcastReceiver。

Activity的安全主要体现在Activity访问权限的控制和Activity被劫持。

2. BroadcastReceiver安全

BroadcastReceiver 翻译成中文为广播接收者,用于处理接收到的广播,广播接收者的安全分为发送安全与接收安全两个方面。

广播是一种广泛运用的在应用程序之间传输信息的机制,广播的分类及其特点如表2所示,而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件;广播接收者用于接收广播 Intent,广播 Intent 的发送是通过调用 Context.sendBroadcast、Context.sendOrderedBroadcast来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收。在AndroidManifest.xml中,组件的Action是通过Intent过滤器来设置的,使用了Intent过滤器的Android组件默认情况下都是可以被外部访问的,解决方法就是组件声明时设置它的android:exported属性为False,这样广播接收者只能接收本程序组件发出的广播。

表2 广播的分类及其特点

广播的使用场景如下。

1)同一App内部的同一组件内的消息通信(单个或多个线程之间)。

2)同一App内部的不同组件之间的消息通信(单个进程)。

3)同一App具有多个进程的不同组件之间的消息通信。

4)不同App之间的组件之间消息通信。

5)Android系统在特定情况下与App之间的消息通信。

3. Service安全

在Android系统开发中,Service是一个重要的组成部分。如果现在某些程序中的某部分操作是很耗时的,那么可以将这些程序定义在 Service 中,这样就可以在后台运行,也可以在不显示界面的形式下运行,即Service实际上就是相当于一个没有图形界面的Activity程序,而且当用户执行某些操作需要进行跨进程访问的时候也可以使用Service来完成。

Service的分类有本地服务和远程服务。

(1)本地服务(Lo cal)

该服务依附在主进程上,不是独立的进程。本地服务在一定程度上节约了资源,由于是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多。主进程被杀死后,服务便会终止。

(2)远程服务(Remote)

该服务是独立的进程,对应进程名格式为所在包名加上指定的android:process字符串。由于是独立的进程,因此,在Activity所在进程被杀死的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。但由于独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。一些提供系统服务的Service通常是常驻的。

Service组件已知产生的安全问题有:权限提升、Service劫持、拒绝服务和消息伪造。

Intent-filter 与 Exported 属性配置方法有:私有 Service 不定义 Intent-filter 并且设置Exported为False;公开的Service设置Exported为True,Intent-filter可以定义或不定义;内部或可信Service设置Exported为True,Intent-filter不定义。

安全研发建议有:应用内部使用的Service应设置为私有;针对Service接收到的数据应该验证并谨慎处理;内部Service需要使用签名级别的protectionLevel来判断是否未内部应用调用;不建议在 onCreate 方法调用的时候决定是否提供服务,建议在 onStartCommand、onBind、onHandleIntent等方法被调用的时候做判断;使用显示意图只针对有明确服务需求的情况尽量不发送敏感信息,可信任的Service需要对第三方可信公司的App签名做校验。

4. ContentProvider安全

Android 平台提供了 ContentProvider,将一个应用程序的指定数据集提供给其他应用程序。这些数据可以存储在文件系统、SQLite数据库中,或以任何其他合理的方式存储。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。

ContentProvider通过URI(统一资源定位符)来访问数据,URI可以理解为访问数据的唯一地址。

ContentProvider 类提供了一种机制用来管理以及与其他应用程序共享数据。在与其他应用程序共享Content Provider的数据时,应该实现访问控制,禁止对敏感数据未经授权的访问。

更细化的权限优先于作用域较大的权限。

(1)统一读写提供程序级别权限

一个同时控制对整个提供程序读取和写入访问的权限,通过<provider>元素的android:permission 属性指定。

(2)单独的读取和写入提供程序级别权限

针对整个提供程序的读取权限和写入权限。可以通过<provider>元素的 android:readPermission属性和android:writePermission属性指定它们。它们优先于android:permission所需的权限。

(3)路径级别权限

针对提供程序中内容 URI 的读取、写入或读取/写入权限。可以通过<provider>元素的<path-permission>子元素指定想控制的每个 URI。对于指定的每个内容 URI,都可以指定读取/写入权限、读取权限或写入权限,或同时指定所有3种权限。读取权限和写入权限优先于读取/写入权限。此外,路径级别权限优先于提供程序级别权限。

(4)临时权限

一种权限级别,即使应用不具备通常需要的权限,该级别也能授予对应用的临时访问权限。临时访问功能可减少应用需要在其清单文件中请求的权限数量。当启用临时权限时,只有持续访问所有数据的应用才需要“永久性”提供程序访问权限。

假设需要实现电子邮件提供程序和应用的权限,如果要允许外部图像查看器应用显示提供程序中的照片附件,为了在不请求权限的情况下为图像查看器提供必要的访问权限,可以为照片的内容 URI 设置临时权限。对电子邮件应用进行相应设计,使应用能够在用户想要显示照片时向图像查看器发送一个 Intent,其中包含照片的内容 URI 以及权限标识。图像查看器可随后查询电子邮件提供程序以检索照片,即使查看器不具备提供程序的正常读取权限,也不受影响。

要想启用临时权限,请设置<provider>元素的 android:grantUriPermissions 属性,或向<provider>元素添加一个或多个<grant-uri-permission>子元素。如果使用了临时权限,则每当用户从提供程序中移除对某个内容URI的支持,并且该内容 URI 关联了临时权限时,都需要调用Context.revokeUriPermission。

该属性的值决定可访问的提供程序范围。如果该属性设置为True,则系统会向整个提供程序授予临时权限,该权限将替代您的提供程序级别或路径级别权限所需的任何其他权限。

如果此标识设置为False,则必须向<provider>元素添加<grant-uri-permission>子元素。每个子元素都指定授予的临时权限所对应的一个或多个内容URI。

要向应用授予临时访问权限,Intent 必须包含 FLAG_GRANT_READ_URI_PERMISSION和/或 FLAG_GRANT_WRITE_URI_PERMISSION 标识。它们通过 setFlags方法进行设置。

如果android:grantUriPermissions 属性不存在,则假设其为False。

数据安全

1. 外部数据安全

外部存储通常是指将数据存入到设备的SD卡上。

外部存储是一种不安全的数据存储机制,因为存储到SD卡上的文件默认是提供给others读文件的权限的,设备上安装的其他App只要在其AndroidMenifest.xml上声明如下的语句。

<uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE'></uses-permission>

那么该App就具有了对于SD卡的完全的读写权限,即是说一个App放在SD卡上的任何数据都可以被其他的App进行读/写操作,所以将重要数据存储在SD卡上具有相当大的安全隐患。

2. 内部数据安全

内部数据存储主要分为两种方式:SharedPreference存储和File存储。内部数据存储的安全问题主要需要注意的是创建的模式以及向文件中写入的内容。

SharedPreference 存储是一种轻量级的数据存储方式,它的本质是基于 XML 文件存储Key-Value键值对数据,通常用来存储一些简单的配置信息。

File存储即常说的文件(I/O)存储方法,常用于存储大量的数据。

内部数据存储通常较为安全,因为它们可以受到Android系统的安全机制的保护。

Android的安全机制本质上就是Linux的安全机制,系统会为在Android系统上运行的每一个App创建一个进程,并为该进程分配一个UID。Android系统将会为每一个App创建一个特定的目录/data/data/app_package_name,这个目录的权限只与UID相关,且只有UID关联的用户才有该目录相关的权限。

因此,在对应目录下生成的SharedPreference文件与File文件如果以正确的方式去创建将会受到Android系统权限机制的保护。

这个正确的创建方式是指文件创建的模式,SharedPreference与文件的创建模式主要有以下3种。

MODE_PRIVATE:默认的创建模式,该进程的 UID 对应的用户将会对该文件拥有完全的控制的权限,而其他UID的用户将没有权限去读/写文件。

MODE_WORLD_WRITABLE:该权限将允许设备上所有的App对于该文件拥有写的权限。

MODE_WORLD_READABLE:该权限将允许设备上所有的App对于该文件拥有读的权限。

为了确保内部数据的安全,有如下建议。

(1)创建文件时的权限控制

如果在创建文件的时候没有注意控制权限,那么该文件的内容将会被其他的应用程序所读取,这样就造成了用户相关信息的泄露,SharedPreference中存储的往往是一些免登token、session id等和用户身份息息相关的重要信息,因此,在创建的时候一定要注意选取好创建的模式;免登token也一定要具有时效性,否则与存储了明文的用户名和密码无异。

(2)SharedPreference中不要存入明文密码等重要信息

由于有Root的存在,那么Root过后的手机就打破了Linux提供的沙箱机制,那么无论以何种方式去创建SharedPreference都已经不再安全了,如果存储的是用户明文的密码,那么用户的密码将会泄露,因此,绝对不要向SharedPreference中写入任何无时效性的重要的数据。

3. 通信数据安全

这里的通信数据安全是指软件与软件、软件与网络服务器之间进行数据通信时,所引发的安全问题。

软件与软件的通信,Android有4大组件:Activity、Content Provider、Service、Broadcast Receiver。

这些如果在Androidmanifest.xml配置不当,会被其他应用调用,引起风险。Android应用内部的Activity、Service、Broadcast Receiver等,它们通过Intent通信,组件间需要通信就需要在Androidmanifest.xml文件中暴露组件。

Intent的两种基本用法:一种是显式的Intent,即在构造Intent对象时就指定接收者;另一种是隐式的Intent,即Intent的发送者在构造Intent对象时,并不知道也不关心接收者是谁,有利于降低发送者和接收者之间的耦合。

带来的风险有恶意调用、恶意接收数据、仿冒应用、恶意发送广播、启动应用服务、调用组件、接收组件返回的数据、拦截有序广播等。

常见的有以下的防护手段。

(1)最小化组件暴露

不参与跨应用调用的组件添加android:exported="false"属性,这个属性说明它是私有的,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。

<activity android:name=".LoginActivity" android:label="@string/app_name" android: screenOrientation="portrait" android:exported="false">

(2)设置组件访问权限

参与跨应用调用的组件或公开的广播、服务设置权限。

① 组件添加android:permission属性。

<activity android:name=".Another" android:label="@string/app_name"android:permission="com.test.custempermission"> </activity>

② 声明属性

<permission android:deion="test" android:label="test" android:name="com.test.custempermission"android:protectionLevel="normal"></permission>

protectionLevel有4种级别:Normal、Dangerous、Signature、SignatureOrSystem。Signature、SignatureOrSystem级别只有相同签名时才能调用。

③ 调用组件者声明

<uses-permission android:name="com.test.custempermission"/>

(3)暴露组件的代码检查

Android 提供各种 API 在运行时检查、执行、授予和撤销权限。这些 API 是android.content.Context类的一部分,这个类提供有关应用程序环境的全局信息。

网络数据通信可能面临的攻击是网络流量嗅探,如果网络上传没有加密的数据,网络嗅探就能截获到数据,ARP攻击可以轻松嗅探到账号、密码等。比较常见是通过HTTPS,HTTPS能有效地防止数据暴露、防止第三方截获应用的通信数据。

Android中实现HTTPS基本就这两种方式,一种是不验证证书,一种是有验证证书(预防钓鱼)。

第二种方式实现复杂一些,需要将cer证书转换成BKS类型。这种方式也只能简单地防止钓鱼,不能有效地防止钓鱼。防止钓鱼最终还是靠用户分辨,在正规渠道下载应用。应用证书也能起到验证客户端的功能,使用证书验证客户端不合适,如果使用证书验证客户端,证书必须存放在应用程序中或使用时下载,Android应用都是一个APK文件,很容易获取到里面的文件,如果是下载方式,更容易通过下载地址获取。如果想验证客户端的话,使用so文件封装数据更好。


http://www.hkcw.cn/article/WhaahTWjGX.shtml

相关文章

《九州天空城》全集剧情分集介绍

剧情介绍 电视剧《九州天空城》由杨磊执导,张若昀、关晓彤、鞠婧祎、刘畅、陈若轩等联袂主演。九州天空城剧情讲述了在神秘力量的驱使下,人族和羽族在维系了短暂的和平之后,再度陷入了剑拔弩张的战争局面所引发的故事。 太古时代,羽族因为有飞翔能力,被天下苍生视为神明。…

【喜报】皓月集团当选中国食品土畜进出口商会第八届副会长单位!

喜报 吉林省长春皓月清真肉业股份有限公司 2024年4月8日至9日,中国食品土畜进出口商会举行第八届会员代表大会暨中国食品农产品贸易高质量发展大会。根据中国食品土畜进出口商会章程规定,经第八届会员代表大会第一次会议审议通过,皓月集团当选第八届副会长单位,任期五年(20…

《锦绣未央》大结局,你真的觉得未央没有爱过南安王?

《锦绣未央》大结局了,太多人都死了,真的已经变成了仅剩未央,我突然感到很悲凉,为南安王感到悲伤。 在你们眼中,他或许是一个心狠手辣又恶毒的人,亦或者只是一个移动的表情包。网友眼中的他,是这样!或者是这样!展开全文但是,我看见了一个不一样的南安王。 他从小,亲眼看见自己的…

中国国防部微博 26日正式上线

如皋商务信息网讯 &#xa0;5月25日上午10点18分,国防部新闻事务局官方微博“国防部发布”上线后发布了第一条微博,引起了网友的关注。 虽然第一条微博不足百字,但信息量大,风格轻松活泼。截至昨天下午5时,半天时间粉丝数已升至近2万,数千网友点赞、转发、评论。 26…

号称十万只鹰里才出一只的极品猛禽,“万鹰之神”——海东青

声明:本文转载自网络,如有侵权,请在后台留言联系我们进行删除,谢谢!“羽虫三百有六十,神俊最数海东青。性秉金灵含火德,异材上映瑶光星。”“羽虫三百有六十,神俊最数海东青。性秉金灵含火德,异材上映瑶光星。” 以上话语是康熙皇帝对“海东青”的评价,夸赞了“海东青…

揭开意大利五大顶级奢侈品牌 LOGO 背后的故事part 1

一个成为全球顶级品牌的产品,除了百年的企业历史和产品品质外,其品牌LOGO同样有着很精彩的故事。 今天AA为大家介绍的是意大利五大顶级奢侈品牌 LOGO 背后的故事。 通过具象的品牌 LOGO 来窥探那些引领无限设计与时尚灵感的顶级品牌,又是什么样的灵感促使了他们品牌诞生。 一…

原创九里香的正确养殖方法

九里香,又称石辣椒、九秋香,是一种常绿灌木或小乔木,以其优美的株姿、秀丽的枝叶和浓郁的花香而备受喜爱。在养殖九里香的过程中,了解其生长习性、掌握正确的养护方法至关重要。本文将详细介绍九里香的养殖方法,帮助爱好者们轻松养出健康美丽的九里香。一、盆土选择 九里香…

动漫美图丨给你不一样的《偷星九月天》,高清壁纸等你拿!

应这位小伙伴“冷月微雪”的评论要求,小漫本期就给大家分享,曾超级火的人气漫画《偷星九月天》。说来惭愧,小漫还没看过这一部剧情,就不加介绍了,如果你也喜欢这部漫画的,就来收图吧!另外,其他的小伙伴,如果也有自己特别想要的哪部动漫壁纸,也可以在评论区留言给小漫…

如何化解房子东北角是厕所的问题

: 在我们的家庭中,厕所是一个不可或缺的空间。然而,从风水的角度来看,厕所通常不宜位于房子的东北角。本文将为您解答如何化解这一问题,并探讨厕所位于东北角会对我们的生活产生哪些影响。 一、如何解决房子东北角是厕所的问题? 1. 如果无法改变厕所的位置,可以尝试调整马…

200张故宫绝密老照片

许多朋友反映,故宫的老照片他们没看到。向上查找历史文章又太费时间,要求我们重发一下。好吧好吧,就借修订重发的机会再选一下。由于公众平台限制一次上传照片数量,因此有的图片可能会有重复,请朋友们谅解。解放后,开始装修故宫时的情景。 破败如此,说啥呢?展开全文这是…

《爱情公寓》海报曝光,网友直呼不忍直视!

在娱乐圈中,有一些明星的造型让人印象深刻,不仅是因为其与众不同,更是因为其雷人到让人难以直视。今天我们要讨论的就是《爱情公寓》的主演们,在一组非主流造型海报中的惊人形象变化。曾经,关谷神奇、曾小贤、美嘉、陈美嘉等《爱情公寓》主角们,是我们心目中的亲切角色,…

燃气引入管、穿墙管、穿楼板管质量管控必备知识!燃气工程人员收藏、学习

嗨,这里是博燃网。我们将分享即时的燃气资讯、权威的燃气政策、全面的燃气科普。欢迎关注博燃网,共同守护燃气安全! 2021年6月13日清晨,湖北十堰发生市政燃气管道设施泄漏爆炸事故,造成重大人员伤亡和财产损失,影响广泛,相信大家记忆犹新,也将人们的注意力和精神又一次…

原创55岁邓文迪去看秀又把人美到!穿绿色花裙可真嫩,又活成少女了

当地时间5月9日,邓文迪又去看秀了,前几天刚刚出席了Metgala红毯,真是又美又霸气。邓文迪最新亮相,和年轻MM同框,丝毫不输。要知道邓姐前几天和23岁女儿一起走红毯的时候,女儿都输给了她。邓文迪选择了一身非常清新的绿色花裙去看秀,这样绿色丝绸裙子虽然不是那种非常紧身…

香港石岗军营两次大阅兵,受阅一次,荣耀一生!

石岗军营是香港驻军面积最大的营区,拥有香港仅有的两座机场之一。 是驻军历年向香港市民开放的军营,也是驻军历史上两次盛大阅兵仪式的举办地。这两次大阅兵,如风驰电掣,似山呼海啸,组成了一曲震撼大地的军威交响乐,在香港新界的巍巍群山间经久回荡。这威武阵势,向世人展…

Windows 10技巧:轻松找回Windows 7三大经典

Windows 10很好很强大,但因为变化太大,很多怀旧的同学还是更想念Windows 7上的一些经典功能。其实,很多经典都是可以找回来的,也不太费事儿。今天我们就说其中三个: 1、Aero Glass毛玻璃效果 这个效果在Windows Vista上刚出来的时候很多人都骂华而不实,Windows 8时代取消…

军刀、军刺也分使用场合?盘点几种不同形制的刺刀使用的场合!

各种军用刺刀长短不一,外形各异,但根据其刀身及截面的形状,可以把它们大致分为锥形刺刀以及刀/剑形刺刀两大类。但不管哪一类,其形状都是由这种刺刀的用途、杀伤性能和强度等要求,以及传统习惯等综合决定的。锥形刺刀的截面多数设计成三角形、十字形,一般带有明显的棱角突…

素材分享——15张可爱的版画创意美术作品

课前导读 版画是视觉艺术的一个重要门类。广义的版画可以包括在印刷工业化以前所印制的图形普遍具有版画性质。当代版画的概念主要指由艺术家构思创作并且通过制版和印刷程序而产生的艺术作品,具体说是以刀或化学药品等在木、石、麻胶、铜、锌等版面上雕刻或蚀刻后印刷出来的图…

余文乐和杨幂接吻,太投入连舌头都伸出来了,当年被认为假戏真做

余文乐和杨幂曾经合作过一部叫做《春娇与志明》的电影,电影中的吻戏也成为了当年的热门话题。片中男女主角余文乐和杨幂在吻戏中展现出高度恩爱,甚至被部分观众认为是假戏。虽然这样的争议一直存在,但不得不佩服演员们的专业精神。而且相比于吻戏,一些女演员甚至愿意接受更…

昆明公认的14大美女,一个比一个惊艳!倒数第二个简直是人间极品!

蓝天是她的外衣, 河水是她的眼睛, 绿树是她的秀发, 城市是她的面庞。 春天她活泼灵动, 夏天她风华绝代, 秋天她楚楚动人, 冬天她温润明媚。 她是“我们眼中第一大美女”! 展开全文她,叫昆明。其实,昆明不仅自己是个大美女, 就连她所辖的市、区也漂亮得不像话。…

原创梁静雅与前夫认识4个月闪婚 年轻当选韩国小姐 曾出演综艺强心脏

近日,韩国实力派演员梁静雅出演了综艺节目《黄金渔场-radio star》,一同出演出演的嘉宾还有尹海英、金承秀、崔完静等人。这次在节目中梁静雅首次分享了自己离婚2年后的心境,成为了大家关注的焦点。展开全文梁静雅在2017年的时候正式宣布与结婚4年的企业家丈夫离婚,不过大家…