APP数据持久化安全分析:SharedPreferences

前言

所谓“数据持久化”,就是将内存中的数据(如对象)等存储至可永久保存的存储设备(如文件)中。在Android,数据持久化一般有4种:
1、数据库存储
2、文件存储
3、SharedPreferences存储
4、网络存储
其中SharedPreferences是我们最常用的一种方式,它以键值对的格式存储数据。SharedPreferences有4种操作模式:
1、Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
2、Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件
3、MODE_WORLD_READABLE:表示当前文件可以被其他应用读取
4、MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入
由于后两种将数据暴露给了其他应用,本身就存在很高的安全隐患,因此并不建议开发人员使用!!!(在4.2之后,系统也摒弃了后两种)

研究背景

SharedPreferences除了存储功能外,还可以进行数据的共享,既包括应用程序之间的共享,也包括同一个应用内各组件之间的数据共享。也正因为SharedPreferences的作用十分广泛和方便,几乎所有的APP都会使用。那么,数据的安全问题如何得到有效的保障呢?虽然前面提到允许其他应用读写的操作模式已经被摒弃了,但是由于SharedPreferenes的本质还是文件存储(会将数据存储在xml文件),因此仍然可以利用Root获得文件的访问权限,从而读取文件内容。所以,这种数据持久化方案存在着很大的安全隐患,数据的安全无法得到充分的保障!本文就是借助一台ROOT后的设备,通过编写一个SP文件读取程序,验证是否可以成功获取数据。

准备工作

1、准备一台ROOT的设备,我这里用的是一台pixel手机(至于如何ROOT,网上有大量的教程)
2、安装一个使用了Sharepreferences的APP

实现原理

1、SharePreference的存储路径为/data/data/"+pkgName+"/shared_prefs
2、获取ROOT权限后,利用“ls”命令遍历上述存储路径
3、利用“cat”命令展示文件内容

核心代码

1、遍历SharePreference目录,获取所有xml文件

public static List<String> getSpListByPkg( String pkgName) {
        List<String> sps = new ArrayList<>();
        ProcessBuilder pb = new ProcessBuilder("/system/bin/sh");
        pb.directory(new File("/"));//设置shell的当前目录。
        try {
            Process proc = pb.start();
            //获取输入流,可以通过它获取SHELL的输出。
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            BufferedReader err = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
            //获取输出流,可以通过它向SHELL发送命令。
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc
                    .getOutputStream())), true);
            out.println("pwd");
            out.println("su root");//执行这一句时会弹出对话框(以下程序要求授予最高权限...),要求用户确认。
            out.println("cd /data/data/"+pkgName+"/shared_prefs");//这个目录在系统中要求有root权限才可以访问的。
            out.println("ls -l");//打印所有的xml文件
            out.println("exit");
            out.println("exit");
            // proc.waitFor();
            String line;
            while ((line = in.readLine()) != null) {
                if(line.endsWith(".xml")){
                    String[] infos = line.split("\\s+");
                    if (infos.length == 8) {
                        sps.add(infos[7]);
                    }
                }
            }
            in.close();
            out.close();
            proc.destroy();
        } catch (Exception e) {
            System.out.println("exception:" + e);
        }

        return sps;
    }

2、利用“cat”命令展示xml内容

public static String getSpDetail(String pkgName,String spName) {
        String content = "";
        ProcessBuilder pb = new ProcessBuilder("/system/bin/sh");
        pb.directory(new File("/"));//设置shell的当前目录。
        try {
            Process proc = pb.start();
            //获取输入流,可以通过它获取SHELL的输出。
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            BufferedReader err = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
            //获取输出流,可以通过它向SHELL发送命令。
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc
                    .getOutputStream())), true);
            out.println("pwd");
            out.println("su root");
            out.println("cd /data/data/"+pkgName+"/shared_prefs");
            out.println("cat "+spName);
            out.println("exit");
            out.println("exit");
            String line;
            while ((line = in.readLine()) != null) {
                if(!line.equals("/")) {
                    content += line + "\n";
                }
            }
            in.close();
            out.close();
            proc.destroy();
        } catch (Exception e) {
            System.out.println("exception:" + e);
        }

        return content;
    }

效果截图

APP数据持久化安全分析:SharedPreferences
APP数据持久化安全分析:SharedPreferences

总结

1、SharedPreferences只是提供文件的存储与读取功能,并不保障数据的安全,因此对于敏感数据,需要自己进行加密处理
2、虽然系统不再允许其他应用操作SharedPreferences,但是仍可以通过ROOT权限成功获取到数据

上一篇:移动安全 - 敏感信息安全 - SharedPreferences


下一篇:Android文件存储