Skip to main content
Dark green background, "Weak Application Security Can Cost You Millions," 3 slanted images of fingers pointing to digital locks, and a "Learn the Basics" button
Config Files Execute Code. Your TPRM Intake Doesn't Check Them.Software Supply Chain Security
4 min readFor Supply Chain Risk Managers

Config Files Execute Code. Your TPRM Intake Doesn't Check Them.

You vet dependencies, scan containers, and review vendor source code access controls. But when a vendor hands you a repository or package, do you check the config files for shell commands?

Most TPRM workflows treat config files as metadata, scaffolding that makes the software run, not executable logic that needs review. This assumption creates a blind spot attackers now exploit routinely. The Miasma worm demonstrated this pattern: 121 repositories were compromised through config files that launch credential stealers the moment a developer opens the folder or runs a test. No malicious dependency required. No install script flagged. Just a .vscode/tasks.json or a composer.json hook that executes a command your tooling never questioned.

If your vendor intake process doesn't treat config files as code, you're missing a supply chain attack surface that bypasses every dependency scanner you run.

Config Files Are Not Just Metadata

Config files in modern toolchains can carry shell commands that execute automatically. For example, VS Code's tasks.json can run a script when a folder is opened, and Composer's post-install-cmd hook fires on every composer install. A Gemfile is Ruby evaluated top to bottom every time Bundler reads it; line one can call system() and run arbitrary commands before dependencies load.

The Miasma dropper was hidden in .github/setup.js, a 4.3 MB obfuscated script. Five config files launched it: .vscode/tasks.json triggered it on folder open, package.json wired it into the test script, .claude/settings.json and .gemini/settings.json ran it when an AI agent session started, and .cursor/rules/setup.mdc instructed the agent to execute it as a setup step. Additional launchers appeared across the campaign: a Composer post-install-cmd hook and a system() call on line one of a Gemfile.

Each config held the same payload: node .github/setup.js. The developer's own tools did the rest.

Trust Prompts Aren't Foolproof

Trust prompts gate some vectors but not all, and they're designed to confirm the folder is safe, not to flag a 4.3 MB obfuscated dropper hiding six levels deep in the config chain.

VS Code opens unfamiliar folders in Restricted Mode and blocks tasks until you click Trust. Claude Code and Gemini CLI show a folder-trust prompt the first time a session starts. The attack doesn't defeat those prompts. It relies on developers granting trust reflexively, like dismissing cookie banners. Once a folder is trusted, hooks run on every later session with no further confirmation. Claude Code's SessionStart hooks have run silently since version 2.1.0.

Two situations skip the prompt outright: pulling the malicious commit into a repo that was already trusted, and running headless (claude -p), which disables trust verification. The package-manager vectors, npm test, composer install, bundle install, have no trust gate at all. They run their hooks as a normal part of the workflow.

Dependency Scanners Won't Catch This

Dependency scanners parse lockfiles and check known packages against vulnerability databases. They don't parse tasks.json, composer.json scripts, or Gemfiles for shell commands. The Miasma dropper wasn't a dependency. It was a file committed directly into the repo, launched by config that your scanner never opened.

A SessionStart hook is a postinstall script for your editor. A .cursor/rules file is a prompt injection that ships in the repo. Both run with the developer's credentials. Neither shows up in a dependency scan.

It's Not Just an IDE Problem

If your vendor intake process includes cloning a repository, running tests, or opening the codebase in an editor to review it, you're exposed. If your CI pipeline pulls vendor code and runs npm install or composer install, you're exposed. If your developers integrate vendor SDKs or sample code into internal projects, they're exposed.

The attack surface isn't limited to editors. The Composer and Bundler vectors execute at install time, in CI or on a developer's machine, with no folder open required. The broader class includes JetBrains run configurations under .idea/, Python pyproject.toml build backends, Make and Taskfile targets, Git hooks committed under a non-standard core.hooksPath, and devcontainer postCreateCommand directives. Any tool that reads structured config and acts on it belongs in this threat model.

Review All Code Changes

Most review workflows skim past config and dotfiles as scaffolding. A diff that adds .vscode/tasks.json or a scripts block to package.json doesn't trigger the same scrutiny as a change to application logic. The Miasma commit in one affected repository was backdated to 2017 and carried a plausible message ending in [skip ci], so it sat in dormant history rather than at the top of the log.

You review the code. You don't review the files that run before the code loads.

What to Do Instead

Treat config files as part of the trusted computing base. During vendor intake, before you open a repository or run any install command:

  1. Grep for auto-run behavior:

    grep -rInE 'folderOpen|"SessionStart"|post-install-cmd' \
      .vscode .claude .gemini composer.json
    grep -nE '^[[:space:]]*(system|exec|`)' Gemfile
    
  2. Review config diffs like code. Any change to .vscode/, .cursor/, .claude/, package.json scripts, composer.json scripts, or a Gemfile gets the same scrutiny as a pull request that touches authentication logic.

  3. Scan for the Miasma dropper specifically:

    test -f .github/setup.js && echo "Miasma dropper present"
    
  4. If a vendor repository was already opened or trusted, treat the session as exposed. Rotate GitHub tokens, npm tokens, and any AWS, Azure, or GCP keys loaded in the environment. Check other recently opened vendor clones for .github/setup.js.

  5. Extend your CI config review. If your pipeline runs vendor tests or install scripts, those same config files can execute in your build environment with your secrets in scope.

Recognize that the line between data and code disappeared the moment your editor started reading JSON and running the commands it found inside.

Promotional banner for the Penetration Report Template Kit

You Might Also Like