Reminder: Check Your Projects Before Importing Them

Building an Android project through Gradle — from Android Studio or from the command line — often results in arbitrary foreign code to run on your development machine. If that code contains malware, that malware has the run of your development machine and therefore has quite a bit of potential for damage.

So, before you go importing or building that really cool Android demo or library that you saw on GitHub, practice safe compiling, and examine the project first.

Replace the Gradle Wrapper

The Gradle Wrapper consists of:

  • A shell script (gradlew) and batch file (gradlew.bat)

  • A JAR (gradle/wrapper/gradle/gradle-wrapper.jar) used by the shell script and batch file

  • A properties file (gradle/wrapper/gradle/, containing, among other things, a distributionUrl property pointing to a copy of Gradle

When you run gradlew from the command line, if there is a .gradle/ directory in your project and it contains a copy of Gradle, gradlew delegates the work to it. Otherwise, it downloads the ZIP file pointed to by that distributionUrl, unZIPs it into .gradle/, then delegates to it.

This is fraught with security issues, as the random GitHub project could have:

  • Modified the shell script or batch file

  • Modified the JAR

  • Hacked a copy of Gradle, then have distributionUrl point to it

(and if the repo contains .gradle/, that too is a risk, though that usually that is blocked by .gitignore)

Worse, while Android Studio does not use the shell script, batch file, or JAR, it will blindly trust whatever copy of Gradle is pointed to by distributionUrl, download and unZIP it, and use it immediately to build your project. There is no attempt at tamper detection, nor is there any warning that you are downloading a copy of Gradle from some strange location rather than one of the standard distribution points. I even hacked a copy of Gradle and demonstrated to Google that Android Studio 2.2RC will happily build a project using the hacked version (to which Google responded that this “works as intended”).

The best solution is to replace all of that before attempting to use the project from the command line or attempting to import it into Android Studio. To do this:

  • Download and install a standalone copy of Gradle on your development machine

  • Examine the existing file and its distributionUrl to try to determine what version of Gradle the project wants

  • From the project root directory, run gradle wrapper --gradle-version ..., where the ... is the version of Gradle that you want (e.g., 2.14.1)

Of note, do not use gradlew for that third step — use the standalone copy of Gradle that you installed.

This will replace all of the Gradle Wrapper files with clean versions, including having distributionUrl point to an official copy of Gradle.

Examine Gradle Plugins and Compile-Time Annotation Processors

Both of these result in code that is downloaded and executed on your development machine. If you see plugins or processors in the various build.gradle files in the project, ask yourself: do you trust them? Do they seem to be common or popular ones, or are they something obscure?

Unlike the Gradle Wrapper scenario, I do not know if there is much that you can do to address this. It is up to you to determine how important that project is and whether it is worth the risks of using those plugins or processors.

There may be other security issues in the build process — these are the ones that have come to mind.