Checking for Poisoned Projects

Yesterday, Google wrote about a campaign to hack the machines of security researchers. One means of doing that was via malware embedded in a Visual Studio project:

After establishing initial communications, the actors would ask the targeted researcher if they wanted to collaborate on vulnerability research together, and then provide the researcher with a Visual Studio Project. Within the Visual Studio Project would be source code for exploiting the vulnerability, as well as an additional DLL that would be executed through Visual Studio Build Events. The DLL is custom malware that would immediately begin communicating with actor-controlled C2 domains.

(here, “C2” means “command and control”, not a cell in the classic game of Battleship)

I have not used Visual Studio in a couple of decades, and I am rather surprised that one can contain a Windows DLL. Shipping binaries around like that used to be frowned upon, just for this sort of reason, but convenience has come to the forefront in modern software development.

Android has its equivalent problems, courtesy of conventions around Gradle. I have warned about these for years — the earliest warning I have found is from 2015. But, in light of this and the SolarWinds hack, let me “re-up” my warnings about importing and running random projects that you find… including just about anything on GitHub.

Yes, even my projects.

RULE #1: Only Use a distributionUrl That You Trust

Whenever you want to use a project from a semi-random source, go into gradle/wrapper/gradle-wrapper.properties and look at the distributionUrl value:

distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip

You only want to use a distributionUrl that seems safe. Primarily, that will be a URL pointing to services.gradle.org. In the future, it would not shock me if Google started hosting Gradle binaries, in which case we may come to trust some google.com domain. And, in a few organizations, you may have some dedicated tools server, in which case your projects would point to it.

Anything else is highly suspect.

This URL points to the copy of Gradle that will be used by Android Studio and other tools to build your app. If this points to a hacked copy of Gradle — one that works but also contains malware — your development machine or CI server could be compromised, much as would the security researchers who opened the malware-laden Visual Studio project.

It would be lovely if Android Studio would maintain a distributionUrl domain whitelist and would warn users if they are importing a project with an unrecognized domain. I suggested it in 2016. Google declined.

RULE #2: Only Use a gradlew That You REALLY Trust

gradlew is a shell script. gradlew.bat is a batch file. They each in turn will run code from the gradle/wrapper/gradle-wrapper.jar file. These too represent executable code, commonly shipped with projects, that will run on your development machine.

The good news is that Android Studio and CI servers will not usually use these files. They use the Gradle Tooling API. So, usually these binaries are only executed when you manually request them.

If you created the project from Android Studio, you may as well trust those binaries, as you are trusting Android Studio itself. However, for a project that you are getting from some public Web site, those binaries could have been altered — its unlikely that you are going to decompile gradle-wrapper.jar and go looking for malware in it. And such altered binaries would run on your development machine or wherever else you use gradlew.

The good news is that gradlew is rather thin. If you have a complete copy of Gradle installed, you can generate a clean Gradle Wrapper (as these files are called) using the wrapper task (gradle wrapper). Or, you should be able to just replace the files with copies from some known-to-be-good source. Or, simply delete them, particularly if you are not likely to use them.

In most of my public projects, I ship gradle-wrapper.properties for easy import into Android Studio, but I do not ship the Gradle Wrapper files. Nobody should be trusting me for their Gradle Wrapper.

It would be wonderful if Google would warn developers about the risks of untrusted Gradle Wrapper files. I suggested it last April; perhaps this one will be adopted.


There are other vectors for malware in a project. For example, you would be wise to examine the roster of Gradle plugins and annotation processors used by the project, as those too represent code that will run on your development machine at the request of the project. In particular, pulling from unrecognized artifact repositories would be a major warning sign.

It is relatively unlikely that you will encounter a poisoned project. However, as the SolarWinds debacle demonstrates, the cost can be extremely high.

Having tons of projects out in places like GitHub and GitLab has been a massive benefit to modern software development. At the same time, in some respects, building one of those projects is little better than finding some USB drive in a parking lot, taking it to the office, and plugging it into your computer. Evil people are catching on to this, and if we are not careful, we will pay the price for the convenience of modern app build processes.