Android Security: Scanning your app for known vulnerabilities

Known vulnerabilities exist for libraries common to Android development such as OkHttp and Apache Commons I/O. The importance of such an issue is highlighted by its position in the OWASP 2017 Top 10 as A9 - Using Components with Known Vulnerabilities.

Our Android apps are using more and more third-party libraries like these and in turn our direct dependencies often depend on their own set so how do you ensure you know about these vulnerabilities and keep your app secure?

The National Vulnerability Database can be queried to determine what security issues your use of open source software may bring you. What is it and how do we use it?

What is the National Vulnerability Database?

The NVD is a U.S. government repository containing details of publicly published security related software flaws. These flaws are linked to the Common Vulnerabilities and Exposures dictionary along with a score for the severity of the risk involved. The NVD provides downloads of its database making it possible to cache the data locally along with querying it for any matches.

What is the Common Vulnerability and Exposures dictionary?

CVE (Common Vulnerabilities and Exposures) is a free for public use list of publicly known cybersecurity vulnerabilities. It was set up to ensure there was a common name (the CVE identifier) that can be used when discussing and sharing information about a particular vulnerability. There is exactly one identifier per vulnerability along with a standardized description.

Scanning your app

Although it is possible to download the NVD data directly yourself, fortunately, OWASP provide a tool to do just this.

The OWASP Dependency Check utility, maintained by Jeremy Long, identifies your projects dependencies and reports on any known, publicly disclosed, vulnerabilities. It keeps itself up-to-date using the NVD data feeds. Due to the size of the data feeds an initial download can take over 10 minutes, however as long as the tool is run at least once every 7 days it can be kept current with small incremental downloads.

For Android developers, the tool is available as a Gradle plugin, dependency-check-gradle as well as command line and Maven. This makes it incredibly simple to implement into your project.

The dependency-check-gradle plugin appears in maven central so you need to make sure that is available, if not already.

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.owasp:dependency-check-gradle:4.0.0'
}
}

For the simplest implementation, you just need to apply the plugin.

apply plugin: 'org.owasp.dependencycheckAnalyze'

Running the plugin is as simple as executing the following on the command line which will generate an HTML report.

./gradlew dependencyCheckAnalyze

The disadvantage of the above is that you need to specifically execute the dependencyCheckAnalyze command. Security tests like this check should be part of your standard build and as such you may prefer to add a dependency to it so it runs automatically for all developers in your team by adding the following to your app/build.gradle file.

tasks.check.dependsOn(tasks.dependencyCheckAnalyze)

The app outputs an HTML report to app/build/reports/dependency-check-report.html.

Image for post
Image for post
An example HTML report from dependency-check-gradle showing no vulnerabilities

With any luck, as the screenshot above shows, you will have no vulnerabilities.

Using the plugin in an Android Kotlin project you may find some vulnerabilities due to dependencies of the Kotlin annotation processor as well as Lint amongst other things. Fortunately, the plugin provides two parameters that can help, scanConfigurations and skipConfigurations where you can specify a list of configuration names to use or skip. Android generates so many configurations it’s easier to set which to use through scanConfigurations rather than those to skip. I use the code below in app/build.gradle to find the relevant dependencies:

dependencyCheck {
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
}
}

Configuring the plugin to fail the build

By default, the plugin is setup so the build never fails. I’m certainly of the opinion that any vulnerability should cause a failure unless you explicitly exclude it.

Ensuring the build fails is as simple as configuring the failBuildOnCVSS field to a value between 0 and 10. The Common Vulnerability Scoring System (or CVSS) is an open framework for communicating the characteristics and impacts of vulnerabilities. The higher the value the greater the risk. By using a value of zero we can ensure any severity of vulnerability will fail the build.

The following would be added to the app/build.gradle file.

dependencyCheck {
failBuildOnCVSS 0
}

Accepting risks by suppressing vulnerabilities

If there are vulnerabilities found then no doubt you will take a deeper look at the offending library to determine if it contains a threat for you. Perhaps you don’t use the particular functionality at risk and so you want to suppress the warning. This is done by supplying a suppressionFile. The following would be added to your app/build.gradle file.

dependencyCheck {
suppressionFile file("dependency-suppression.xml").toString()
}

An example dependency-suppression.xml file may look like the following:

<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
<suppress>
<notes>
<![CDATA[
file name: apps-flyer-android-2.3.1.18.jar
old incident that is already fixed
]]>
</notes>
<sha1>43b08c12ae622987b165ede9b3ba099913d2552f</sha1>
<cpe>ape:/a:appsflyer:appsflyer<cpe>
</suppress>
</suppressions>

Alternative tools

I could only find one alternative for scanning dependencies and reporting on their vulnerabilities, a Maven plugin called enforce-victims-rule, which is discussed in Detecting vulnerable Java dependencies at build time. It’s use in a modern Android project is certainly harder and would require some significant rewriting to turn it into a Gradle plugin. At the time of writing I was also unable to connect through to the data source.

Conclusions

New vulnerabilities are discovered all the time so it is important to constantly scan your dependencies against the NVD database so any changes are picked up immediately and can be investigated.

The dependency-check-gradle plugin is a good first step in ensuring the third-party components you use don’t have any publicly known vulnerabilities. But herein lies the problem, there may be countless unpublished vulnerabilities so this tool does not negate the need to do the analysis yourself to determine the severity of any threats a library could contain.

#buildsecureapps

Matt Dolan has been eating doughnuts and developing with Android since the dark days of v1.6.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store