开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情
用dependencyCheck保证Android应用安全
一个验证第三方库不存在安全漏洞的工具
简介
在开发Android应用程序的时候, 我们依赖于许多第三方库. 可能是网络, 图像处理, 图表...正如我们喜欢说的, "为什么我们要重新发明轮子?". 虽然这句话是对的, 但同样重要的是要意识到, 这些库是由热情的人建立的, 并遵循一般的行业标准(代码覆盖率、测试...), 但它们也不能免于错误或安全漏洞.
dependencyCheck前来拯救
谢天谢地的是, 我们有安全研究人员在一端帮助寻找漏洞, 以及dependencyCheck, 这个工具可以扫描你的应用程序的依赖关系, 并在一个库被破坏时向你发出警报. 该工具通过Gradle任务运行, 可以很容易地集成到你的CI/CD系统(如Jenkins)中.
在Android项目中设置
多亏了Gradle, 通过dependencyCheck来设置Android项目是非常直接的. 因此, 让我们前往gradle.build文件并添加这个依赖, 你可以在这里检查最新的版本:
# ./build.gradle
dependencies {
classpath 'org.owasp:dependency-check-gradle:6.5.0.1'
}
在App模块的顶部, 添加这个插件:
# ./app/build.gradle
apply plugin: 'org.owasp.dependencycheck'
最后, 我们要为Android应用配置插件:
# ./app/build.gradledependencyCheck {
failBuildOnCVSS = 0
scanConfigurations = configurations.findAll {
!it.name.startsWithAny('androidTest', 'test', 'debug') &&
it.name.contains("DependenciesMetadata") && (
it.name.startsWithAny("api", "implementation", "runtimeOnly") ||
it.name.contains("Api") ||
it.name.contains("Implementation") ||
it.name.contains("RuntimeOnly")
)
} .collect {
it.name
}
}
启动第一次分析
现在我们准备启动第一次分析, 希望我们的应用程序不包含太多的漏洞.
打开一个终端, 导航到你的安卓项目:
$ ./gradlew dependencyCheckAnalyze --infoChecking for updates and analyzing dependencies for vulnerabilities
...
Generating report for project app
Found 38 vulnerabilities in project app...
kotlin-compiler-embeddable-1.4.10.jar (pkg:maven/org.jetbrains.kotlin/kotlin-compiler-embeddable@1.4.10, cpe:2.3:a:jetbrains:kotlin:1.4.10:*:*:*:*:*:*:*) : CVE-2020-29582
...
然后你可以在这里找到该报告:
./app/build/reports/dependency-check-report.html
如何修复漏洞
在上面的例子中, 我们可以看到38个漏洞. 让我们更好地了解这一点, 以便我们能够修复它.
我们可以看到kotlin编译器和CVE编号:CVE-2020-29582
这里我们可以看到, 这个漏洞已经在1.4.21中被修复了, 所以我们把Kotlin版本更新到1.4.32,这是1.4分支的最新版本.
一般来说, 更新"z"次要版本(X.y.z)就可以了(除非你的项目很老), 并且可以防止你的项目发生破坏性变化.
有时候, 很难找到一个软件包被标记为漏洞的原因, 这种情况发生在有问题的软件包实际上是另一个软件包的依赖关系:
./gradlew app:dependencies+--- androidx.databinding:databinding-runtime:7.0.3
| +--- androidx.collection:collection:1.0.0 -> 1.1.0
| | --- androidx.annotation:annotation:1.1.0 -> 1.2.0
上面的树显示了你的一些依赖包是如何工作的. 上面, databinding-runtime需要collection, 集合需要collection.
处理假阳性
你有时会发现假阳性, 幸好, dependencyCheck允许你抑制警告. 在这个例子中, 我们有一个Kotlin 1.4.0的假阳性, 而我们实际上包括1.4.32.
在app/build.gradle的dependencyCheck部分, 我们将使用参数"suppressionFile"并提供包含抑制规则的文件的路径:
# ./app/build.gradle
dependencyCheck {
suppressionFile = 'config/owasp/suppressions.xml'
...
}
suppressions.xml文件将包含'suppression'规则:
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
<suppress>
<notes><![CDATA[
file name: kotlin-stdlib-1.4.0.jar
]]></notes>
<packageUrl regex="true">^pkg:maven/org.jetbrains.kotlin/kotlin-stdlib@.*$</packageUrl>
<cve>CVE-2020-15824</cve>
</suppress>
</suppressions>
这些规则可以在报告中找到:
从报告中获取suppress规则的例子.
现在, 该项目没有漏洞, 应用程序是安全的!
在CI/CD中导入dependencyCheck
现在我们已经修复了一切, 如果能定期检查漏洞就更好了, 理想情况下我们应该把它配置到CI/CD中.
使用GitHub Actions, 你可以添加以下内容:
# ./.github/workflows/github-actions.yml
- name: Check for vulnerabilities
run: ./gradlew dependencyCheckAnalyze
送达通知
这篇文章基于SQLCipherPerformance资源库, 我时常用它来实现我在文章中解释的内容. 请看一下这个提交, 以获得所有细节.
总结
Android和Java社区正在提供伟大的工具, 以确保我们的应用程序和用户的安全. 在这个例子中, 实现是相对简单的. 如果你对保护你的安卓应用感兴趣, 可以看看我的关于这个问题的其他文章. 谢谢你的阅读,也欢迎你👏以示支持!
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情