跳过内容

MASTG-TEST-0003: 敏感数据日志测试

已弃用测试

此测试已**弃用**,不应再使用。**原因**:MASTG V2 中提供新版本

请查看以下涵盖此 v1 测试的 MASTG v2 测试

概述

此测试用例侧重于识别系统和应用程序日志中的任何敏感应用程序数据。应执行以下检查

  • 分析源代码以查找与日志记录相关的代码。
  • 检查应用程序数据目录中是否存在日志文件。
  • 收集系统消息和日志,并分析其中是否存在任何敏感数据。

作为避免潜在的敏感应用程序数据泄露的一般建议,除非认为应用程序需要或明确标识为安全(例如,作为安全审核的结果),否则应从生产版本中删除日志记录语句。

静态分析

应用程序通常会使用 Log 类Logger 类 来创建日志。要发现这一点,您应该审核应用程序的源代码,以查找任何此类日志记录类。 通常可以通过搜索以下关键字来找到这些类

  • 函数和类,例如

    • android.util.Log
    • Log.d | Log.e | Log.i | Log.v | Log.w | Log.wtf
    • Logger
  • 关键词和系统输出

    • System.out.print | System.err.print
    • logfile
    • logging
    • logs

在准备生产版本时,您可以使用诸如 Proguard(包含在 Android Studio 中)的工具。 要确定是否已删除 android.util.Log 类中的所有日志记录函数,请检查 ProGuard 配置文件(proguard-rules.pro)中是否存在以下选项(根据此 删除日志记录代码的 ProGuard 示例 和这篇关于 在 Android Studio 项目中启用 ProGuard 的文章)

-assumenosideeffects class android.util.Log
{
  public static boolean isLoggable(java.lang.String, int);
  public static int v(...);
  public static int i(...);
  public static int w(...);
  public static int d(...);
  public static int e(...);
  public static int wtf(...);
}

请注意,上面的示例仅确保将删除对 Log 类方法的调用。 如果要记录的字符串是动态构建的,则构建该字符串的代码可能会保留在字节码中。 例如,以下代码发出一个隐式的 StringBuilder 来构造日志语句

Java 示例

Log.v("Private key tag", "Private key [byte format]: " + key);

Kotlin 示例

Log.v("Private key tag", "Private key [byte format]: $key")

但是,编译后的字节码等效于以下日志语句的字节码,该语句显式构造字符串

Java 示例

Log.v("Private key tag", new StringBuilder("Private key [byte format]: ").append(key.toString()).toString());

Kotlin 示例

Log.v("Private key tag", StringBuilder("Private key [byte format]: ").append(key).toString())

ProGuard 保证删除 Log.v 方法调用。 其余代码 (new StringBuilder ...) 是否会被删除取决于代码的复杂性和 ProGuard 版本

这是一个安全风险,因为(未使用的)字符串会将纯文本数据泄漏到内存中,这可以通过调试器或内存转储来访问。

不幸的是,对于此问题没有银弹,但一种选择是实现自定义日志记录工具,该工具采用简单的参数并在内部构造日志语句。

SecureLog.v("Private key [byte format]: ", key);

然后配置 ProGuard 以删除其调用。

动态分析

至少使用一次所有移动应用程序功能,然后识别应用程序的数据目录并查找日志文件(/data/data/<package-name>)。 检查应用程序日志以确定是否已生成日志数据;某些移动应用程序会在数据目录中创建和存储自己的日志。

许多应用程序开发人员仍然使用 System.out.printlnprintStackTrace 而不是适当的日志记录类。 因此,您的测试策略必须包括应用程序启动、运行和关闭时生成的所有输出。 要确定 System.out.printlnprintStackTrace 直接打印了哪些数据,您可以使用 Logcat,如“基本安全测试”一章的“监控系统日志”部分中所述。

请记住,您可以通过按如下方式过滤 Logcat 输出来定位特定应用程序

adb logcat | grep "$(adb shell ps | grep <package-name> | awk '{print $2}')"

如果您已经知道应用程序 PID,您可以直接使用 --pid 标志。

如果您希望某些字符串或模式出现在日志中,您可能还需要应用进一步的过滤器或正则表达式(例如,使用 logcat 的 regex 标志 -e <expr>, --regex=<expr>)。