合并1 :将敏感数据分配给堆对象,然后对其进行乱序处理。 只泄漏了常量数据。
数组访问1 :将污染值和未污染值存储在数组中,然后泄漏未污染值。 数组索引是常量。 数组访问2 :将污染值和未污染值存储在数组中,然后泄漏未污染值。 计算阵列索引。 阵列副本1 :将受污染的值存储在数组中,然后使用System.arraycopy将数据复制到新数组,然后泄漏到日志中。 排列到字符串1 :IMEI存储在String的数组中,然后使用Arrays.toString()将其转换回String。 哈希映射访问1 :将受污染和未受污染的值存储在哈希映射中,然后泄漏未受污染值。 映射键是常量。 列表访问1 :污染值和未污染值都存储在列表中。 只有未着色的值会泄漏。 多维数组1 :将受污染的值存储在二维数组中,并通过指向包含受污染值的切片的引用访问该值。
匿名Class1 :为匿名内部类中的位置更新注册回调处理程序,并在回调中泄漏传入的位置数据。 按钮1 :用户单击按钮后调用接收器。 按钮处理程序是通过XML定义的。 按钮2 :只有按特定顺序单击按钮才会导致数据泄漏。 按钮3 :在另一个回调处理程序中注册了一个新回调。 第二个处理程序泄漏第一个处理程序获得的数据。 按钮4 :用户单击按钮后调用接收器。 按钮处理程序是使用include指令通过XML定义的。 按钮5 :IMEI是在Activity的onCreate()期间获得的,随后通过布局的xml中定义的onClick回调泄漏。 请注意,第一次单击仅将IMEI存储到按钮提示中。 只有第二次点击才会真正泄漏。 位置泄漏1 :注册侦听器以进行位置更新,存储值并在生命周期中稍后泄漏。 位置泄漏2 :与LocationLeak1类似,但活动类直接实现回调接口。 位置泄漏3 :与LocationLeak1类似,但回调处理程序位于使用接口与活动解耦的专用类中。 方法覆盖1 :覆盖内部Android方法以隐藏泄漏。 多处理程序1 :包含两个活动和两个处理程序,如果正确的活动与正确的处理程序一起使用,则不会泄漏任何数据。 订购1 :在初始化变量的处理程序注册之前泄漏变量内容。 寄存器全局1 :源和接收器都是全局(应用程序级)生命周期处理程序的一部分。 注销1 :在调用回调之前注册并直接注销回调。 因此,回调中的代码永远不会泄漏任何数据。
现场灵敏度1 :受污染和未受污染的数据都存储在数据对象中; 未着色的值被泄漏。 现场敏感性2 :与FieldSensitivity1类似,但源和接收器调用分布在整个生命周期中。 现场灵敏度3 :受污染和未受污染的数据都存储在数据对象中; 被污染的价值被泄露了。 源和接收器调用分布在整个生命周期中。 现场灵敏度4 :在污染字段之前发送字段内容。 继承的对象1 :基于条件选择对象的实际类型。 只有一种可能导致泄漏。 对象灵敏度1 :将受污染的值写入对象,将未受污染的写入相同类型的另一个对象。 泄漏未着色的值。 对象灵敏度2 :将受污染的值写入字段,然后用未被污染的数据覆盖它。
回音器 :接收数据并将其回传给发送方。 发送SMS :读取设备ID,通过Echoer传递,然后通过文本消息发送。 开始结果活动1 :读取用户的地理位置(通过GPS),通过Echoer传递,然后将其写入文件。
活动沟通1 :包含使用静态字段进行通信的两个活动。 活动沟通2 :IMEI在一个Activity中获得,并存储在Intent的额外部分中,用于启动下一个Activaty,然后该Activity会将IMEI泄漏到日志中。 活动沟通3 :使用类名启动另一个“活动”。 IEMI在要启动的活动中泄漏。 活动沟通4 :启动另一个“活动”的意图是通过连接两个常量字符串创建的。 要启动的活动泄漏了作为Intent的附加项传入的IMEI。 活动沟通5 :使用常量组件的Name和Intent.setComponent启动“活动”。 启动的“活动”将IMEI泄漏到日志中。 活动沟通6 :启动另一个活动的意向通过LinkedList的add()传递,并使用LinkedList.get()检索。 检索到的Intent用于启动泄漏的Activity。 活动沟通7 :创建Activity类,并使用实例对象上的getClass()检索其类名。 然后使用类名启动第二个Activity,该Activity从Intent的extra中泄漏IMEI信息。 活动沟通8 :Intent启动另一个Activity的操作通过LinkedList.get()传递并检索。 检索到的字符串用于启动泄漏的“活动”。 广播TaintandLeak1 :IMEI是在活动中获得的,并存储在以编程方式注册的BroadcastReceiver的Intent之外的Intent中。 接收方泄漏IMEI信息。 部件不在清单1中 :IMEI在一个Activity中获得,并存储在Intent中,以启动不在AndroidManifest.xml中的泄漏Activity。 由于无效,因此不会发生泄漏。 事件排序1 :IMEI获取并存储在次要活动(InFlowActivity)的SharedPreferences中。 第一个活动(OutFlowActivity)启动第二个活动。 第二次启动第二个活动时,IMEI会泄漏到日志中。 意向接收器1 :活动导致受污染的值泄漏。 意向接收器2 :与IntentSink类似,但该值是在XML中定义的回调方法中发送的。 意向来源1 :两个受污染的泄漏:第一个是受污染的值使用startActivityForResult的意图泄漏到另一个应用程序。 另一个是onActivityResult方法将意图作为受污染的数据进行记录。 服务通信1 :IMEI被获取并发送到服务,然后该服务会泄漏Messenger处理程序中的信息。 共享首选项1 :IMEI是在一个“活动”中获取的,并存储在另一“活动”泄漏的SharedPreferences中。 单体1 :IMEI存储在一个“活动”中的单例对象中,并在另一个“活动”中泄漏。 无法解决的Intent1 :应用程序尝试在无法静态解析的Intent中启动Activity。 两个Activity中的一个可以基于随机布尔值启动,并且它们都会将IMEI从启动Activity泄漏到日志。
活动生命周期1 :对跨活动生命周期分布的源和汇的调用。 活动生命周期2 :从包含泄漏受污染值的生命周期方法的超类继承的活动类。 活动生命周期3 :对跨实例状态处理方法分布的源和汇的调用。 活动生命周期4 :在上获取污染值 onPause() 并在稍后重新启动活动时泄漏。 活动保存状态1 :IMEI在onSaveInstanceState()期间通过捆绑包的持久性保存,并在下次onCreate()时泄漏 应用程序生命周期1 :在启动应用程序时获取机密值,并在主活动的onResume()方法中发送。 应用程序生命周期2 :在启动应用程序时获取秘密值,并在应用程序的低内存回调中发送。 应用程序生命周期3 :在初始化内容提供程序时获取机密值,并将其泄漏到应用程序的onCreate()方法中。 异步事件排序1 :在onResume()期间获取IMEI,并在onStop()期间通过在onLowMemory()中覆盖来泄漏IMEI。 广播接收器生命周期1 :对广播接收器生命周期中分布的源和汇的调用。 广播接收器生命周期2 :敏感数据在onCreate()中读取,并在动态注册的广播接收器中发送。 事件排序1 :IMEI是在第一次调用onLowMemory时获得的,在第二次调用onLawMemorys时泄漏,但只有在两者之间没有发生onContentChanged()。 碎片生命周期1 :对跨片段生命周期分布的源和汇的调用。 服务生命周期1 :对跨服务生命周期分布的源和汇的调用。 服务生命周期2 :IMEI在onStartCommand结束时获取,并存储到服务的字段中。 服务命令第二次启动时泄漏。 共享首选项更改1 :onCreate(),IMEI被放入SharedPreferences,并触发onSharedPrefenceChanged(),然后将IMEI泄漏到Android日志。
克隆1 :IMEI被添加到链接列表,列表被克隆到新列表,然后新列表中受感染的成员被泄漏。 DirectBuffer(直接缓冲区) :受污染的ByteBuffers不足/过度的测试用例。 例外情况1 :将受污染的值保存到局部变量中,引发异常并在异常处理程序中发送该值。 例外情况2 :将受污染的值保存到本地变量中,隐式引发异常(ArrayIndexOutOfBounds),并在异常处理程序中发送数据。 例外情况3 :将受污染的值保存到局部变量中,但不会调用将其发送出去的异常处理程序。 例外4 :抛出包含受污染值的异常并将其发送到异常处理程序中。 工厂方法1 :从Android操作系统中包含的工厂方法获取LocationManager,读取位置并泄漏。 回路1 :包含简单循环和数据泄漏。 回路2 :通过回调检索位置信息并通过嵌套循环泄漏。 序列化1 :通过ObjectOutputStream和ObjectInputStreamIMEI获取并序列化/反序列化。 源代码特定1 :使用不寻常的代码构造 a=p? b:c。 启动具有机密的进程1 :IMEI是通过ProcessBuilder的start()获取和泄漏的。 静态初始化1 :将受污染的值传递到静态初始化方法中。 静态初始化2 :在类的静态初始化过程中获取敏感数据,并在非状态代码中泄漏 静态初始化3 :IMEI是在静态初始值设定项期间获得的,存储并覆盖在“活动”的字段中,该字段在开始时未被污染。 字符串格式设置符1 :IMEI被传递给格式化程序,然后格式化的缓冲区在泄漏到日志之前被转换回String。 字符串模式匹配1 :IMEI与.*正则表达式匹配,匹配的组被泄漏。 字符串到字符数组1 :IMEI被获取并存储在char[]中,然后在泄露到日志之前将其转换为String。 字符串到输出流1 :获取IMEI并通过ByteArrayOutputStream作为String字节传递回String。 无法访问的代码 :将受污染的数据传递到从未调用的方法中。 虚拟调度1 :根据单击计数器的不同,会实例化一个或另一个类。 然而,实际上只有一个类泄漏数据,这是唯一一个泄漏常量字符串的类。 虚拟调度2 :基类中的方法返回未着色的信息,派生类之一中的相同方法返回敏感(IMEI)信息。 该信息随后通过短信泄露。 * 虚拟调度3 :两个类实现了一个接口,但其中只有一个类返回敏感数据。 然而,泄漏发生在仅返回常量数据的另一个实现上。 * 虚拟调度4 :类似于VirtualDispatch3,但类型信息稍多。
应用程序建模1 :将IMEI存储在Application的对象中,然后在其他Activity中泄漏它。 直接泄漏1 :通过活动的SMS读取并发送设备id 创建时() 事件。 非活动活动 :禁用活动中的数据泄漏。 LogNoLeak(日志无泄漏) :将未着色的数据写入日志文件。 模糊处理1 :此APK包含自己的android.telephony实现。 电话管理器。 然而,在真实设备上,预加载的操作系统实现将始终隐藏自定义的操作系统,并且您将始终获得真实的IMEI。 在Galaxy Nexus 4上进行测试,但不能保证模拟器。 图书馆1 :不是独立的测试用例,是Library2的一部分。 图书馆2 :IMEI在自定义库中读取,然后在应用程序中泄漏。 私人数据泄漏1 :包含各种挑战的摘要测试用例。 私人数据泄漏2 :泄漏密码字段中的值。 私人数据泄露3 :IMEI被写入一个文件,再次读取,然后泄露。 公共API字段1 :获得IMEI并将其转换为2个浮点数,如PointF的x和y。 PointF的值泄漏。 公共API字段2 :IMEI作为数据持有者检索并存储到Intent.action。
隐含流量1-4 :隐式流的测试用例。
反思1 :敏感数据存储在反射类的字段中,然后直接再次读取并泄漏。 反思2 :敏感数据存储在反射类的字段中,使用“未知”类中实现的方法再次读取并泄漏。 反思3 :敏感数据使用setter存储在反射类中,使用getter读回,然后泄漏。 未使用目标类的类型信息。 反思4 :使用反射类中的函数读取敏感数据,并使用同一反射类中另一个函数泄漏。
异步任务1 :敏感数据在onCreate()中读取,并在使用Android的AsyncTask机制启动的专用线程中发送。 Java线程1 :敏感数据在onCreate()中读取,并在使用Java的正常线程机制启动的专用线程中发送。 Java线程2 :敏感数据在onCreate()中读取,并在使用Java的Runnable机制启动的专用线程中发送。 执行人1 :敏感数据在onCreate()中读取,并在使用Java的Executor机制启动的专用线程中发送。 织机1 :敏感数据在onCreate()中读取并排队等待托管Android Looper的自定义线程,该线程的处理程序会发送数据。
仿真程序检测内容提供商1 :此测试用例通过检查内容提供商中的IMEI来检测Android模拟器。 如果应用程序在真实手机上运行,IMEI只会在活动中通过短信发送。 仿真程序检测_IMEI1 :此测试用例通过截断从IMEI计算的位置泄漏的机密数据来检测Android模拟器。 在模拟器上,IMEI应为00..0。 EmulatorDetection_PlayStore1仿真程序 :此测试用例通过手机上是否安装了Play Store应用程序来检测Android模拟器。 IMEI仅在应用程序在真实手机上运行时通过短信发送。
贡献了40个应用程序 麻省理工DroidSafe团队 http://mit-pac.github.io/droidsafe-src/ 一些组件间和应用程序间测试用例由来自 卢森堡大学