
Introducing MavenGate: a supply chain attack method for Java and Android applications | Oversecured Blog
MavenGate is Oversecured's research on hijacking Maven dependencies by buying expired domains behind groupIds on Maven Central and JitPack. It found 6,170 of 33,938 checked domains (18.18%) vulnerable, and tested the attack with its own com.oversecured:hello-world library. It lists defenses (Gradle verification-metadata.xml, PGP signatures) and proposes changes to repository signing.
What it is
MavenGate is Oversecured's name for hijacking a Maven dependency by buying the expired domain behind its groupId. All Maven-based builds, including Gradle, are affected. The default build configuration does no validation of dependencies. Oversecured reported the issue to over 200 companies, including Google, Facebook, Amazon, Microsoft, Adobe, LinkedIn and Netflix.
How it works
Maven Central and JitPack verify a groupId through a DNS TXT record on the matching domain. If the original owner lets the domain lapse, an attacker who buys it can claim the groupId. Claiming only works in a repository where no account already manages that groupId. If one does, the attacker would have to persuade the repository's support team to transfer it. The page says it has no information on those transfer procedures.
Oversecured tested this on its own groupId, com.oversecured, with a hello-world library. On Maven Central, the claim was confirmed within seconds of adding the TXT record. On JitPack, the steps were binding a GitHub repository, granting private-repo access and adding a TXT record that references the GitHub username.
Results with JitPack added to the Gradle repository list:
- With JitPack above mavenCentral(), version 1.0 was downloaded from JitPack.
- Version 1.1 came from JitPack regardless of its position in the list. Android Studio also prompted an upgrade to it.
flowchart TD
A[Attacker owns groupId domain] --> B{Attacker repo order in victim build}
B -->|Above legitimate repo| C[Existing versions replaced]
B -->|Below legitimate repo| D[Publish new higher version]
D --> E[Wait for victim to upgrade]
F[Signature check in verification-metadata.xml] -.blocks.-> C
F -.blocks.-> DA library's dependencies are resolved using the repository list of the consuming project, not the library's own. Transitive dependencies are therefore exposed in the same way.
Preconditions / Affected
- A direct or transitive dependency whose groupId domain (or io.github.* GitHub username) is available to register.
- No hash or signature checking in the consuming project. The new-version attack works even when the attacker's repository is listed lower.
Scale, from Maven Central groupIds converted to domains and checked with GoDaddy Bulk Domain Search (national domains were checked through national registrars):
- Domains: 3,710 of 26,163 vulnerable (14.18%).
- io.github.* projects: 291 of 7,523 vulnerable (3.86%).
- Including private repositories found: 6,170 of 33,938 (18.18%).
Oversecured published the lists as all.txt, vulnerable.txt and the MavenCentral_* files. It argues that a newly registered domain from the list publishing artifacts should alert the community.
What to do
- Audit direct and transitive dependencies for abandoned projects whose domains can be bought.
- Generate gradle/verification-metadata.xml and update it as upstream fixes its signing. The page's command for this was missing from the fetched text.
- Trust only repositories you need.
- To find an unknown signing key, download the file and its .asc, then run
gpg --verify file.asc. It errors without the public key but prints the keyid. Then fetch the key:
gpg --keyserver keyserver.ubuntu.com --recv-keys {key_value}Other key servers named are keys.openpgp.org and pgp.mit.edu.
Library authors should keep their domains registered and publish signed artifacts with findable keys. The page also recommends that repositories reject misconfigured releases and block automatic claiming of vulnerable groupIds.
Caveats
- Hash pinning does not help when versions are updated. Signature checking is the best existing defense, but few dependencies publish their keys.
- Oversecured found that Google's artifacts in its repository are unsigned (Google's response was pending). Many Apache dependencies could not be verified because no key was found on any key server.
- Maven Central's docs call publishing the public key mandatory, but Oversecured uploaded a signed artifact without one and used it.
- Sonatype cannot fully fix this, since an abandoned dependency on JCenter can be hijacked through Maven Central when both are in the list.
- No real-world affected projects are named, because disclosures were still in progress.
- Oversecured's proposals are public keys uploaded with artifacts, a key hash in the dependency declaration (
implementation 'groupId:artifactId:version:sha256signature'), and library authors owning the key hashes of their dependencies.
Organisations named here
- domain takeover
- MavenGate
- T1195.002
Technologies named here
- Gradle
- Maven Central
- Android Studio
- Oversecured
- Maven
- Android
- Java
- Sonatype
- Apache dependencies: public keys not found on any key server
- Dependencies with abandoned domains: 3,710 of 26,163 Maven Central domains (14.18%)
- GnuPG (gpg --verify)
- GoDaddy Bulk Domain Search
- Google Maven repository (google()): artifacts are not signed
- gpg --keyserver keyserver.ubuntu.com --recv-keys
- gradle/verification-metadata.xml
- io.github.* groupIds on Maven Central: 291 of 7,523 (3.86%)
- JCenter (jcenter())
- JitPack (jitpack.io)
- Maven-based technologies, including Gradle
- Overall: 6,170 of 33,938 domains (18.18%) vulnerable
- Published lists: MavenCentral_all.txt, MavenCentral_vulnerable.txt, MavenCentral_github_all.txt, MavenCentral_github_vulnerable.txt, all.txt, vulnerable.txt
Techniques named here
- Attack against existing library versions
- Attack against new library versions
- Dependency hash checksum verification
- Dependency hijacking via expired domain purchase (MavenGate)
- GitHub username re-registration
- Plugin attack on build process
- Repository support groupId transfer request
Threat actors named here
- MavenGate (supply chain attack method against Maven-based Java and Android projects, researched by Oversecured)
Also named here
- JitPack
Related in Supply Chain


