Burn It With Fire: How to Eliminate an Industry-Wide Supply Chain Vulnerability
作者在2019年发现Java依赖解析中使用HTTP而非HTTPS导致的安全漏洞,并推动多方合作关闭HTTP支持、改进默认设置及利用自动化工具修复大量项目,最终消除这一系统性安全漏洞。 2025-7-3 04:59:48 Author: infosecwriteups.com(查看原文) 阅读量:30 收藏

🔥 The supply chain bug that couldn’t be ignored — so I torched it

Jonathan Leitschuh

In 2019, while debugging one of my own builds, I noticed something odd. The build was resolving dependencies over http:// instead of https://. Just one character off — a typo. Harmless? Not quite.

How did this get here?

That tiny misconfiguration opened the door to a broader realization: the Java ecosystem was riddled with this insecure dependency resolution pattern. This wasn’t just my build. It was absolutely everywhere.

The vulnerability itself was simple: if you could man-in-the-middle an HTTP connection, you could inject malicious code into thousands of Java builds. And worse, some of the biggest names in the ecosystem were affected: JetBrains, Apache, Red Hat, Spring, Jenkins, Gradle, ElasticSearch, and many more.

That single character typo led me down a wild multi-year rabbit hole — one that started with uncovering an industry-wide supply chain vulnerability, and ended with a simple mission: driving coordinated changes across artifact hosts, build tools, and open source projects to eliminate the vulnerability class entirely.

This is the story of how I did it — and what I learned along the way.

Dependency resolution is at the heart of every build system. When you build a Java project, tools like Maven and Gradle fetch external libraries — often from public artifact repositories like Maven Central, JCenter, or custom corporate mirrors. These dependencies are downloaded and cached locally.

But for years, many of those download URLs, hard coded in build systems, were configured using plain old http://. No encryption. No integrity checking. No other guarantee the content came from who it claimed to.

Incredibly, back in 2012, Sonatype charged a $10 donation fee for projects to be allowed to use HTTPS with Maven Central (source) — a barrier that predictably saw little adoption.

In defense of Maven Central, they are basically operating as a free CDN for OSS maintainers

In 2014, Max Veytsman wrote about this in his excellent post How to Take Over the Computer of Any Java Developer. His tool, Dilettante, was a proof-of-concept proxy that injected malicious payloads into JARs as they were downloaded over HTTP. It simply rendered a picture of a cat. It could’ve just as easily delivered malware. This blog post, and the resulting outcry, finally pushed Sonatype to offer HTTPS for-free to everyone.

However, years later, many of the same vulnerabilities were still present — not due to malice, but due to typos, insecure defaults, and bad copied & pasted code. After extensive GiHub searches I found the problem was very much still alive, and it was everywhere!

One of the earliest realizations I had was that even if developers fixed their projects and tools improved their defaults, it wouldn’t matter if the servers still allowed insecure downloads. The problem needed to be addressed at the very foundation: the artifact hosts.

So I reached out to the largest public artifact hosts in the JVM ecosystem — Maven Central (Sonatype), JCenter (JFrog), the Gradle Plugin Portal, Spring, JetBrains, Eclipse, and Red Hat — and proposed a coordinated timeline to block all HTTP-based artifact downloads.

To my surprise, many of them agreed.

By January 15, 2020, Maven Central, JCenter, and Spring had all shipped changes to reject HTTP requests. This was a massive milestone. It meant even if a user or build tool tried to fetch dependencies over HTTP, it would simply fail.

This move was covered in official blog posts from:

It was one of the clearest examples of the ecosystem coming together to shut a door — not just for new code, but for old habits and bad defaults.

At the time the shutdown occurred, Sonyatype noted that they were still seeing 20% of their traffic still using HTTP. On and after January 15th, 2020, there were several confused StackOverflow posts asking why builds were suddenly failing.

Once artifact hosts began shutting off HTTP support, the next logical step was ensuring that the build tools themselves would reinforce this security posture. Fixing infrastructure was important — but, as CISA notes in their “Secure by Design” initiative, fixing the developer defaults is just as critical.

While working at Gradle, I authored PR #10065 to introduce a strict mode that required developers to explicitly opt in to resolving dependencies over HTTP. This change ensured that a one-character typo (http:// instead of https://) could no longer silently open a security hole — it had to be intentional.

I reached out to the Bazel team at Google and filed issue #8607. Their response was the creation of the flag:

--incompatible_disallow_unverified_http_downloads

This flag blocks HTTP downloads unless a checksum is provided or a fallback HTTPS URL is available.

I also engaged the maintainers of the Scala build tool, SBT, filing SBT issue #4905. They too responded positively and shipped changes to mitigate the same HTTP repository injection risks.

Each of these tools implemented different mechanisms — opt-in flags, verification requirements, or outright blocks — but the goal was the same: secure-by-default builds that reduce the blast radius of a typo.

While Gradle, Bazel, and SBT responded with relatively swift and thoughtful fixes, Maven proved to be a far harder challenge.

In late 2020, I began a coordinated disclosure process to report a critical issue in Maven: transitive repository injection. Maven projects could inherit http:// repositories from dependencies without the developer even realizing it. It meant you could write a perfectly secure POM — and still get compromised.

My colleague at Gradle, Cédric Champeau, authored a proof-of-concept, and I submitted it while engaging in the back-and-forth disclosure process with the Apache Security Team and the Maven PMC. The back-and-forth stretched across months. Emails went unanswered. Conversations stalled. Multiple reminders were sent. At one point, I had to loop in CERT/CC to escalate.

Meanwhile, I wrote code to scan the entire Maven Central index — parsing millions of POM files to identify real-world usage and generate a list of affected coordinates. The results were staggering. Over 100,000 libraries were affected. Mend later published a public write-up summarizing the issue and its implications, which you can read here: Maven Security Vulnerability: CVE-2021–26291.

Eventually, after significant pressure — and after weeks of unanswered emails, stalled conversations, and repeated follow-ups — I wrote to the ASF security team:

“What fundamentally disturbs me here is that all of us as individuals, and the companies we work for… all play a critical role in protecting the supply chain of the JVM ecosystem. To that end, we’ve all failed in some way here… This game of ‘not my problem, it’s yours’ does nothing to protect users.”

I believed this issue was real. And someone had to push to get it fixed.

CERT/CC eventually threatened to go over the Apache Security Team’s head and issue a CVE for the unpatched vulnerability. This threat finally spurred the Apache Maven team into action. Apache Maven issued CVE-2021–26291 and shipped a fix in version 3.8.1, changing the default behavior to block HTTP repository resolution.

This was a hard-fought win — and one that highlighted just how difficult it can be to drive coordinated change even when the risk is well-documented and easily fixed.

With changes underway across artifact hosts and build tools, I wanted to see just how far I could take this — not just by changing policies or defaults, but by actually eliminating the vulnerable code in the wild. That’s when I built an automation engine for secure pull request generation.

To do that, I built a tool: the bulk-security-pr-generator. In early 2020, I live streamed myself using it to generate 1,596 pull requests in one sitting, patching insecure dependency resolution across the JVM ecosystem. Over the past several years, over 40% of these pull requests have been merged. That means that 600+ OSS repositories that were vulnerable, no longer are.

This wasn’t just a stunt. It was the first successful demonstration that mass vulnerability mitigation via automation was not only possible — it was practical.

That work led me to become the inaugural Dan Kaminsky Fellow, which gave me the time and support to turn this idea into a replicable process: one that could scale security research across entire ecosystems.

The culmination of that work was a talk — actually, many talks:

“Scaling the Security Researcher to Eliminate OSS Vulnerabilities Once and For All”

Imagine a world where a security researcher becomes aware of a security vulnerability, impacting thousands of Open Source Software (OSS) projects, and is enabled to both identify and fix them all at once. […] Let’s not just talk about vulnerabilities — let’s actually fix them at scale.

This talk was presented at:

  • Black Hat USA
  • DEF CON 30
  • GitHub Universe
  • BSides LV
  • SEC-T Stockholm
  • No Hat Italy
  • Code Blue Tokyo
  • IWCon

It told the story not just of fixing vulnerabilities, but of building and demonstrating a new model for open source security work:

  • Find a vulnerability pattern (via CodeQL, GitHub Search, grep, etc.)
  • Automate the search across thousands of repositories
  • Automatically generate PRs with real, reviewable fixes
  • Submit them respectfully, with clear descriptions and opt-out options
  • Contribute those queries upstream to prevent regressions

And most importantly: do all of this in a way that helps maintainers — not burdens them.

The images that AI can come up with are just absolutely wild

If there’s one lesson I’ve taken away from this work, it’s this: eliminating a vulnerability class from an ecosystem requires persistence — and a multipronged strategy.

You can’t assume that someone else will finish the work. You can’t rely on a single fix, a single flag, or a single PR. You have to:

  • Patch the vulnerable consumers
  • Fix the defaults in the tools
  • Change the behavior at the source
  • Coordinate across organizations, vendors, and open source maintainers
  • Follow through until the job is actually done

This wasn’t just a bug to fix — it was a systemic weakness in how the Java ecosystem resolved dependencies. It was an invisible dependency problem hiding in plain sight. And it had to be rooted out on all sides.

Security is rarely about discovering something new. Often, it’s about fixing what we already knew was broken — but at scale, with care, and with follow-through.

We didn’t just patch a bug. We made a vulnerability class obsolete.

And that’s how you burn it with fire.


文章来源: https://infosecwriteups.com/burn-it-with-fire-how-to-eliminate-an-industry-wide-supply-chain-vulnerability-12515516fb56?source=rss----7b722bfd1b8d---4
如有侵权请联系:admin#unsafe.sh