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
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
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
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
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)
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.