【Android学习】Android安全机制

1,实现沙箱化

1)沙箱

对使用者来说是一种安全缓解,对恶意访问者来说是一种限制。

2)Android沙箱

Android应用通常在一个独立的沙箱种运行,即每一个Android应用程序都在它自己的进程中运行,拥有一个独立的Dalvik虚拟机实例。Android这种基于Linux的进程“沙箱”机制,是整个安全设计的基础之一。
具体而言,进程以隔离的用户环境运行,不能相互干扰,比如发送信号或者访问其他进程的内存空间。因此,Android沙箱的核心机制基于以下几个概念:标准的Linux进程隔离、大多数进程拥有唯一的用户ID(UID),以及严格限制文件系统权限。

①Android ID(AID)和UID

Android系统沿用了Linux的UID/GID权限模型,即用户ID和用户组ID,但并没有使用传统的passwd和group文件来存储用户与用户组的认证凭据,作为替代,Android定义了从名称到独特标识符Android ID(AID)的映射表。初始的AID映射表包含了一些与特权用户及系统关键用户(如system用户/用户组)对应的静态保留条目。

在linux中,一个用户标识(UID)识别一个给定用户;在Android上,一个UID则识别一个应用程序。在安装应用程序时向其分配UID。应用程序在设备上存续期间内,其UID保持不变。仅限用于允许或限制应用程序(而非用户)对设备资源的访问。如此,Android的安全机制与Linux内核的安全模型完美衔接!不同的应用程序分别属于不同的用户,因此,应用程序运行于自己独立的进程空间,与UID不同的应用程序自然形成资源隔离,如此便形成了一个操作系统级别的应用程序“沙箱”。

②辅助用户组机制

除了AID,Android还使用了辅助用户组机制,以允许进程访问共享或受保护的资源。例如,sdcard_rw用户组中的成员允许进程读写/sdcard目录,因为它的加载项规定了哪些用户组可以读写该目录。这与许多Linux发行版中对辅助用户组机制的使用是类似的。除了用来实施文件系统访问,辅助用户组还会被用于向进程授予额外的权限。权限是关于允许或限制应用程序(而不是用户)访问设备资源。

3)Android沙箱模型

①应用程序在独立的进程

应用程序进程之间,应用程序与操作系统之间的安全性由Linux操作系统的标准进程级安全机制实现。在默认状态下,应用程序之间无法交互,运行在进程沙箱内的应用程序没有被分配权限,无法访问系统或资源。因此,无论是直接运行于操作系统之上的应用程序,还是运行于Dalvik虚拟机的应用程序都得到同样的安全隔离与保护,被限制在各自“沙箱”内的应用程序互不干扰,对系统与其他应用程序的损害可降至最低。Android种互相不具备信任关系的应用程序相互隔离,独自运行。
Android 是一个多用户系统,每个应用是一个独立的用户。系统为每个应用分配一个唯一的用户标识(UID),并为应用中所有文件设置该用户才能访问的权限。每个进程中有一个独立的VM。每个应用在自己的进程中运行,应用的组件需要执行时,系统创建该进程;当系统内存不存时,系统会销毁该进程。

②应用程序在同一个进程(共享UID)

Android 应用程序运行在它们自己的 Linux 进程上,并被分配一个惟一的用户 ID。默认情况下,运行在基本沙箱进程中的应用程序没有被分配权限,因而防止了此类应用程序访问系统或资源。但是 Android 应用程序可以通过应用程序的 manifest 文件请求权限。
通过做到以下两点,Android 应用程序可以允许其他应用程序访问它们的资源:
i>声明适当的 manifest 权限;
ii>与其他受信任的应用程序运行在同一进程中,从而共享对其数据和代码的访问。
在很多情况下,源自同一开发者或同一开发机构的应用程序,相互间存在信任关系。Android系统提供一种所谓共享UID(SharedUserID)机制,使具备信任关系的应用程序可以运行于同一进程空间。通常 ,这种信任关系由应用程序的数字签名确定,并且需要应用程序在manifest文件中使用相同的UID。
不同的应用程序可以运行在相同的进程中。对于此方法,首先必须使用相同的私钥签署这些应用程序,然后必须使用 manifest 文件给它们分配相同的 Linux 用户 ID,这可以通过用相同的值/名定义 manifest 属性 android:sharedUserId 来做到。通过sharedUserId,拥有同一个User id的多个APK安装包可以配置成运行在同一个进程中.所以默认就是可以互相访问任意数据. 也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的数据库和文件.就像访问本程序的数据一样。这样就为同一个机构发开的不同App之间的数据共享,提供了便利。

2,应用程序签名机制。

1)概念

所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序。
Android通过数字签名来标识应用程序的作者和在应用程序之间建立信任关系,不是用来决定最终用户可以安装哪些应用程序。 应用程序包(.apk文件)必须被开发者数字签名;同一开发者可指定不同的应用程序共享UID,进而运行于同一进程空间,共享资源。
这个数字签名由应用程序的作者完成(可以是自签名的),并不需要权威的数字证书签名机构认证,它只是用来让应用程序包自我认证的。
数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能

2)签名的过程

生成私有、公共密钥和公共密钥证书
对应用进行签名
优化应用程序

3)签名的作用

识别代码的作者。
检测应用程序是否发生了改变。
在应用程序之间建立信任,以便于应用程序可以安全地共享代码和数据。

4)签名的意义

为发布的APK文件进行唯一签名,保证我们每次发布的版本的一致性设置唯一。有2个意义:
1)保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package Name来混淆替换已经安装的程序
2)保证自动更新时,不会因为版本不一致(签名不同)而无法安装

5)数字证书的建立

APK程序的两种模式:调试模式(debug mode)和发布模式(release mode)。

①调试模式(debug mode)

在调试模式下, ADT会自动的使用debug密钥为应用程序签名,因此我们可以直接运行程序。
运行android项目,在目录的bin文件夹下就能找到与项目同名的apk文件,此apk默认是已经使用debug用户签名。

i>debug密钥
ii>存放位置

C:\Users\Xiaopeng.android\debug.keystore Xiaopeng(对应替换为自己操作系统的用户名 )

iii>风险

debug签名的应用程序有这样两个风险:
一是debug签名的应用程序不能在Android Market上架销售,它会强制你使用自己的签名;
二是debug.keystore在不同的机器上所生成的可能都不一样,就意味着如果你换了机器进行apk版本升级,那么将会出现上面那种程序不能覆盖安装的问题。
所以如果软件有很多使用客户,一定要有自己的数字证书来签名。

②发布模式(release mode)

当要发布程序时,开发者就需要使用自己的数字证书给apk包签名 。使用自己的数字证书给APK签名的两种方法:
i>通过DOS命令来对APK签名。
ii>使用ADT Export Wizard进行签名
自动更新的前提:包名一致、签名一致。

6)设置签名

①创建key。如何创建参考第5步的注。
②右击项目,选择Export
③在Android目录下选择Export Android Application,然后next
④选择项目,next
⑤选择Use existing keystore。在Location选择第1步创建的Key。然后输入password。next。
注:没有创建好key可在此处选择Create new keystore。然后填写密钥库信息。即可生成keyy
⑥命名并选择存放的apk位置。

3,权限声明机制

应用程序需要显式声明权限、名称、权限组与保护级别。不同的级别要求应用程序行使此权限时的认证方式不同:Normal级申请即可用;Dangerous级需在安装时由用户确认才可用;Signature与Signatureorsystem则必须是系统用户才可用。

1)概念

①android系统特权分离

Android是一种特权分离(privilege-separated)的操作系统,在Android上运行的每个应用程序都具有各自独立的系统标识(Linux用户ID和组ID),系统各部分有不同的身份标识。因此,Linux上运行的各个应用程序相互独立且与系统无关。

2)android安全架构-“权限许可”机制

Android安全架构的一个中心设计宗旨:认情况下任何应用都没有权限执行对其他应用、操作系统和用户产生不利影响的操作。
为了提供附加细粒度的安全功能:①限定特定的进程能够执行的指定操作②限定对每一个资源点对点的访问的URI许可。
由于内核让每个应用程序运行在独立的线程沙盒中,应用程序必须通过声明所需要而沙盒没有提供的权限来明确的分配资源和数据。Android没有采用会使用户体验复杂并且不利于安全的动态授权机制。应用程序静态的声明他们所需要的权限,在程序安装时Android系统会提示用户同意它们获取这些权限。
应用静态地声明他们所需的权限,在运行时,Android 系统提示用户,以使应用获得准许。

3)四种权限

①通过manifest文件中声明

请求android:name对应的权限。

 <uses-permissionandroid:name="string" />

②通过permission添加自定义权限

    <permission
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:name="com.test.android.ACCESS_FRIENDS_LIST"
       android:description="@string/permission_description"
       android:label="@string/permission_label"
       android:protectionLevel="normal" />

③系统组件权限,如activity组件

<activity
       android:permission="com.test.android.ACCESS_FRIENDS_LIST"

④动态申请权限

Android6.0以后需要加入权限的时候询问用户。
这里提供一个GitHub组件:AndPermission,可通过glide依赖使用。

4)Android权限模型

目标:
①通过列出应用程序可能执行的所有敏感的操作,让用户意识到安装这个应用存在的潜在风险。
②降低风险:
通过限制应用程序访问Android系统敏感的API接口,来降低应用程序对整个系统带来的伤害(比如病毒)。

Android权限四个等级有:
①普通级:
这些权限并不能真正伤害到用户(比如更换壁纸),当程序需要这些权限是,开发者不需要指定程序会自动赋予这些权限。
②危险级:
这些权限可能会带来真的伤害(比如打电话,打开网络链接等),如果要使用它们需要开发者在AndroidManifest.xml中声明对应的权限。
注意:如果在调用需要权限的组件时没有在Manifest.xml中声明权限,则会在运行对应代码段时报异常!!!
③签名级:
如果应用使用的是相同的签名证书时,这些权限会自动授予给声明或者创建这些权限的程序。设计这一层级权限的目的是方便组件间数据共享。
所有的APK(.apk文件)必须使用证书签名,证书的私钥由开发者持有。这个证书用来辨别应用的所有者。证书不必由证书机构来签名,一个完全正当的、也是典型的做法是Android应用使用开发者自己签名的证书。在Android中,证书的作用就是区分应用的所有者。这使得系统能授权或拒绝应用对签名级别权限的获取,以及相同开发者的另外的应用请求被分配相同的Linux标识。
④签名/系统级:
和签名级一样,例外的是系统镜像是自动获取这些权限的,这一层级是专为设备制造商设计的。

5)安装时package

在安装时,Android 给每个 package 一个独特的 Linux 用户 ID 。在某台设备上这个 package 的生命周期里,这个身份一直是不变的。
相同的 package 在不同的设备上UID可能不同;不同的 package在同一个设备上 UID不同。
由于安全增强发生在线程级别,两个package的代码不能在一个相同的线程正常运行,因为他们必须以不同的 Linux 用户运行。使用AndroidManifest.xml中manifext标签的sharedUserId属性来使不同应用被分配相同的用户 ID。通过这样,两个package就被当作同一个应用程序,拥有相同的用户ID和文件权限,但是出于安全目的,只有当两个应用使用相同签名(和拥有相同的sharedUserId)才会被分配相同的用户ID。

6)常用权限

<!-- 发送消息-->  
< uses-permission android:name="android.permission.SEND_SMS"/>  
< !-- 阅读消息-->  
< uses-permission android:name="android.permission.READ_SMS"/>  
< !-- 写入消息-->  
< uses-permission android:name="android.permission.WRITE_SMS" />  
< !-- 接收消息 -->  
< uses-permission android:name="android.permission.RECEIVE_SMS" />  
<!-- 在SDCard中创建与删除文件权限 -->  
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
<!-- 往SDCard写入数据权限 -->  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

4,访问控制机制

传统的 Linux访问控制机制确保系统文件与用户数据不受非法访问。

1)Linux用户与权限

①超级用户(root),具有最高的系统权限,UID为0。
②系统伪用户,Linux操作系统出于系统管理的需要,但又不愿赋予超级用户的权限,需要将某些关键系统应用
文件所有权赋予某些系统伪用户,其UID范围为1~ 499,系统的伪用户不能登录系统。
③普通用户,只具备有限的访问权限,UID 为 500 ~ 6000,可以登录系统获得 shell
在Linux权限模型下,每个文件属于一个用户和一个组,由UID与GID标识其所有权。

2)针对于文件的具体访问权限

定义为可读®、可写(w)与可执行(x),并由三组读、写、执行组成的权限三元组来描述相关权限。
第一组定义文件所有者(用户)的权限,第二组定义同组用户(GID相同但UID不同的用户)的权限,第三组定义其他用户的权限(GID与UID都不同的用户)。

5,进程通信机制

进程内通信
跨进程通信(IPC)

6,内存管理机制

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

7,底层

1)反编译

2)二次打包

重打包即通过反编译后重新加入恶意的代码逻辑,重新打包一个APK文件。

3)代码混淆

项目编译正式包时,默认是开启混淆的,即类名方法名会被混淆成a,b,c,d的样子,增加破解着的难度。
**Android采用的Proguard的开源方案,只能对java类进行混淆。**程序的启动类(Application)和业务类(Activity)都需要注册到AndroidManifest.xml中,Android的几大组件的创建方式是依赖注入的方式,因此不能被混淆。混淆只能对java类进行混淆,并不支持xml这种配置文件,所以Android默认对于Application、Activity、Service、UI相关的类都是不混淆的,而一些通过字符串反射生成类的地方也不能混淆(网络数据转为本地java对象),而jni调用方法也不能混淆。

虽然Android引入了混淆技术,但是由于当前混淆方案的缺陷和Android系统框架中大量使用反射技术,使得很多重要的类不能混淆,这极大的降低了反编译后阅读源码的成本。为了增加破解难度,我们可以把算法放到native代码中,即用C/C++实现算法,通过jni调用。

4)jni

为了防止别人直接调用so文件,在so中判断当前应用的签名,只要别人拿不到你的keystore就没办法伪造你的签名。这样别人只能想办法去破解这个so库。

5)加壳脱壳

加壳:给程序加一层壳,可以用来对原程序进行资源压缩、防调试、防注入、防反编译,也就是说通过一个壳把原来的程序保护了起来。我们知道一个常规Android程序它的所有代码都在dex文件中,程序启动时要先把这个dex文件载入到内存中,所以如果要加壳的话,主要工作就是把原dex文件加密或者隐藏起来,放一个新的壳dex到apk中,程序启动时运行这个壳dex,然后这个壳dex在运行时再加载原dex。
破解原dex的工作变成了破解壳dex了,最终的原理是一样的,需要频繁升级加固方案才能保证安全。

6)进程劫持

进程被劫持一般通过进程注入或者调试进程的方式来hook进程,改变程序运行的逻辑和顺序,从而获取程序运行的内存信息。hook需要获取root权限或者跟被hook进程相同的权限。如果手机没被root,被劫持的可能性还是较小。

7)数据加密

数据在传输过程遭劫持,一般来说是由于数据明文传输或没使用HTTPS。

①对称加密

对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥加密。
优点:使用简单快捷,密钥较短,破译困难。
举例:数据加密标准(DES)、国际数据加密算法(IDEA,比DES的加密性好,而且对计算机功能要求也没有那么高)、3DES、Blowfish、RC4、RC5、RC6和AES。

缺点:

  1. 要求提供一条安全的渠道使通讯双方在首次通讯时协商一个共同的密钥。直接的面对面协商可能是不现实而且难于实施的,所以双方可能需要借助于邮件和电话等其它相对不够安全的手段来进行协商;
  2. 密钥的数目难于管理。因为对于每一个合作者都需要使用不同的密钥,很难适应开放社会中大量的信息交流;密钥的数目难于管理。因为对于每一个合作者都需要使用不同的密钥,很难适应开放社会中大量的信息交流;
  3. 对称加密算法一般不能提供信息完整性的鉴别。它无法验证发送者和接受者的身份;对称加密算法一般不能提供信息完整性的鉴别。它无法验证发送者和接受者的身份;
  4. 对称密钥的管理和分发工作是一件具有潜在危险的和烦琐的过程。对称加密是基于共同保守秘密来实现的,采用对称加密技术的贸易双方必须保证采用的是相同的密钥,保证彼此密钥的交换是安全可靠的,同时还要设定防止密钥泄密和更改密钥的程序。对称密钥的管理和分发工作是一件具有潜在危险的和烦琐的过程。对称加密是基于共同保守秘密来实现的,采用对称加密技术的贸易双方必须保证采用的是相同的密钥,保证彼此密钥的交换是安全可靠的,同时还要设定防止密钥泄密和更改密钥的程序。
    假设两个用户需要使用对称加密方法加密然后交换数据,则用户最少需要2个密钥并交换使用,如果企业内用户有n个,则整个企业共需要n×(n-1) 个密钥,密钥的生成和分发将成为企业信息部门的恶梦。

②非对称加密技术

与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。

公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

基本过程:甲方生成一对密钥并将其中的一把作为公用密钥向其它方公开;得到该公用密钥的乙方使用该密钥对机密信息进行加密后再发送给甲方;甲方再用自己保存的另一把专用密钥对加密后的信息进行解密。甲方只能用其专用密钥解密由其公用密钥加密后的任何信息。

举例: 非对称加密的典型应用是数字签名。
常见的非对称加密算法有:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)、Hash算法(摘要算法)

③Hash算法

是一种单向算法,用户可以通过hash算法对目标信息生成一段特定长度的唯一hash值,却不能通过这个hash值重新获得目标信息。因此Hash算法常用在不可还原的密码存储、信息完整性校验等。

常见的Hash算法有MD2、MD4、MD5、HAVAL、SHA

8,服务器安全

1)被攻击排查

①察看进程,查找异常进程、不常见进程
②在CMD下用netstat -a查看当前打开的端口和已经被监听的端口,将来历不名的关闭(若找攻击来源,监听你的IP一般都在里边,不过没用的,一般都使用代理)
③检查新增加的自启动程序
④关闭多余服务,若是XP保持开机进程在15个左右,除非你的电脑做WEB服务器用
⑤做TCP UDP规则,只限制让常用的端口通过
⑥打好补丁文件

2)如何保证服务器安全

①系统采用Linux服务器
②要设置防火墙,不该开发的端口不要开放
③设置内网连接服务器,外网静止连接,或者只让某些ip有远程连接服务器的权限等

3)防止API 被暴力攻击

①限制一个账号或IP登录次数

比如设置频率限制为每分钟1000次(可以是某个端口,每个ip等等)

②伪造IP地址的防范

你可以发送请求到对方ip地址,伪造的ip地址没有任何response

③防止“短信轰炸机”

①图形验证码、
②限定请求次数、
③流程条件限定:将手机短信验证放在最后进行,比如需要用户必须注册后,或者用不必须填写了某些条件才能进行短信验证。
④归属地是否一致:服务器端检查用户的IP所在地与手机号归属地是否匹配,如果不匹配则提示用户手动操作等。

④服务器接口验证:token、md5、base64

当用户登录成功后,返回一个由Token签名生成的秘钥信息(Token可使用base64编码和md5加密,可以放在请求的Header中),然后对每次后续请求进行Token的封装生成,服务器端在验证是否一致来判断请求是否通过。

劫持token和uid后,可以冒充用户。

一旦用户登录后,服务器就通过token来标识身份。如果这个token被黑客劫持了,他就可以冒充你的身份进行攻击,如果token机制设计不合理,攻击者甚至可以直接暴力去撞token。大部分网站的机制也类似,服务器通过一个sessionId标识用户,攻击者一旦拿到这个sessionId,就可以去冒充一个合法用户。

采取MD5值传输和存储,但是依然存在爆破破解的方法。

例如黑客看到库中一个密码数量比较多,就可以尝试去爆破,加上也可以直接用密码的MD5值去撞库,用MD5(name+pwd)作为密码存储,同样的密码生成的值是不一样的,在一定程度上提高了安全性。

给请求参数添加一个签名

后台服务接收到请求时,先验证签名,签名不正确的话,则不予处理。签名规则五花八门,大致策略就是根据请求参数做一些运算最后生成一个唯一的字符串当做sign。
如何防止攻击者获取到你的签名生成规则?

⑤采用https

线上的api接口开启https访问,这样做的话别人抓包的难度会提高很多,而且https需要秘钥交换,可以在一定程度上鉴别是否伪造IP。
①https并不能阻挡攻击者分析请求接口并发起攻击。
https分单向认证和双向认证,大部分的应用场景是c/s模式,这时通常都是采用的单向认证的方式,也就是说可以保证客户端拿到的数据是后台发送的。这时想攻击确实很难了,除非你能忽悠别人安装并信任你的证书,实际上也并不是做不到,很多人蹭wifi时或者在网上下载一些资源,系统提示要信任什么东西,看都不看就点确定。这些暂时不提,上面提到的那些攻击,都依赖于对后台接口的分析和调用,对于这类攻击者来说,你使用http和https是没有区别的。

⑥服务器端代理请求

针对于网站,这也是解决跨域的方案之一,采用服务器代理可以有效的防止接口真实地址的暴露。

⑦恶意行为分析

当接口存在大量肉鸡攻击的时候,攻击者也同样容易暴露意图,我们可以通过系统分析算法,让攻击者获取不到有效数据,提高攻击成本。

9, Android安全控制

1)应用权限控制

通过控制应用程序的权限防止恶意应用对系统造成破坏,采取的措施包括合理使用系统内置权限和应用程序自定义权限。

2)应用程序签名

采用数字签名为应用程序签名。

3)应用加固

应用加固包括病毒扫描、防注入、防调试、防篡改四个模块,目前行业内已经出现了很多的应用加固解决方案,如360应用加固、腾讯云应用加固、百度应用加固等等。

4)静态代码分析

通过静态代码分析工具lint监测安全隐患,对代码进行优化。

5)防火墙

必要时为Android设备安装防火墙,以防止远程网络攻击。

6)数据存储加密

采用加密的方式保护应用程序敏感数据,如利用SQLCipher加密SQLite数据库。

7)应用程序组件开发的安全要点

Activity, Service, Content Provider, Broadcast Receiver等组件在代码层面应采取的安全措施。它们每一个都可以通过隐式的Intent方式打开,所以这些组件只要不是对外公开的必须在AndroidManifest里面注明exported为false,禁止其它程序访问我们的组件。对于要和外部交互的组件,应当添加访问权限的控制,还需要要对传递的数据进行安全的校验。

10,Webview漏洞

一般由于JS注入。

1)任意代码执行漏洞

①WebView 中 addJavascriptInterface() 接口

addJavascriptInterface 接口引起远程代码执行漏洞。
漏洞产生原因:JS调用Android的其中一个方式是通过addJavascriptInterface接口进行对象映射,代码如下。当JS拿到Android这个对象后,就可以调用这个Android对象中所有的方法,包括系统类(java.lang.Runtime 类),从而进行任意代码执行。 如可以执行命令获取本地设备的SD卡中的文件等信息从而造成信息泄露。

webView.addJavascriptInterface(new JSObject(), "myObj");
// 参数1:Android的本地对象
// 参数2:JS的对象
// 通过对象映射将Android中的本地对象和JS中的对象进行关联,从而实现JS调用Android的对象和方法

解决方案:
Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击
在Android 4.2版本之前采用拦截prompt()进行漏洞修复。
具体步骤如下:

i>继承 WebView ,重写 addJavascriptInterface 方法,然后在内部自己维护一个对象映射关系的 Map;
ii>将需要添加的 JS 接口放入该Map中
iii>每次当 WebView 加载页面前加载一段本地的 JS 代码,原理是:
iv>让JS调用一Javascript方法:该方法是通过调用prompt()把JS中的信息(含特定标识,方法名称等)传递到Android端;
v>在Android的onJsPrompt()中 ,解析传递过来的信息,再通过反射机制调用Java对象的方法,这样实现安全的JS调用Android代码。
vi>关于Android返回给JS的值:可通过prompt()把Java中方法的处理结果返回到Js中

②WebView 内置导出的 searchBoxJavaBridge_对象

产生原因:在Android 3.0以下,Android系统会默认通过searchBoxJavaBridge_的Js接口给 WebView 添加一个JS映射对象:searchBoxJavaBridge_对象,该接口可能被利用,实现远程任意代码。

解决方案:删除searchBoxJavaBridge_接口

// 通过调用该方法删除接口
removeJavascriptInterface();

③WebView 内置导出的 accessibility 和 accessibilityTraversalObject 对象

2)密码明文存储漏洞

WebView默认开启密码保存功能 :mWebView.setSavePassword(true),开启后,在用户输入密码时,会弹出提示框:询问用户是否保存密码;如果选择”是”,密码会被明文保到 /data/data/com.package.name/databases/webview.db 中,这样就有被盗取密码的危险。

解决方案:关闭密码保存提醒,WebSettings.setSavePassword(false)

3)域控制不严格漏洞

即 A 应用可以通过 B 应用导出的 Activity 让 B 应用加载一个恶意的 file 协议的 url,从而可以获取 B 应用的内部私有文件,从而带来数据泄露威胁。

具体:当其他应用启动此 Activity 时, intent 中的 data 直接被当作 url 来加载(假定传进来的 url 为 file:///data/local/tmp/attack.html ),其他 APP 通过使用显式 ComponentName 或者其他类似方式就可以很轻松的启动该 WebViewActivity 并加载恶意url。

使用 file 域加载的 js代码能够使用进行同源策略跨域访问,从而导致隐私信息泄露。

// 设置是否允许 WebView 使用 File 协议,
// 默认设置为true,即允许在 File 域下执行任意 JavaScript 代码
webView.getSettings().setAllowFileAccess(true);     
// 设置是否允许通过 file url 加载的 Js代码读取其他的本地文件
webView.getSettings().setAllowFileAccessFromFileURLs(true);
// 在Android 4.1前默认允许
// 在Android 4.1后默认禁止
// 设置是否允许通过 file url 加载的 Javascript 可以访问其他的源(包括http、https等源)
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);

// 在Android 4.1前默认允许(setAllowFileAccessFromFileURLs()不起作用)
// 在Android 4.1后默认禁止
// 设置是否允许 WebView 使用 JavaScript(默认是不允许)
webView.getSettings().setJavaScriptEnabled(true);  

// 但很多应用(包括移动浏览器)为了让 WebView 执行 http 协议中的 JavaScript,都会主动设置为true,不区别对待是非常危险的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值