Skip to content

Supply chain risk: runtime npx install exposes users to transitive dependency attacks #49

@varunsh-coder

Description

@varunsh-coder

Summary

This action uses npx @datadog/datadog-ci@latest at runtime to install and execute the Datadog CI package. This means every dependency (and transitive dependency) is resolved fresh from npm on each workflow run, with no lockfile or integrity verification. This recently resulted in a real-world supply chain compromise affecting users of this action.

What happened

A malicious version of axios (1.14.1) was published to npm. Because @datadog/datadog-ci declares "axios": "^1.13.5" as a dependency, npm resolved it to the compromised version at install time. The attack chain was:

npx @datadog/datadog-ci@latest
  → @datadog/datadog-ci@5.10.0
    → axios@^1.13.5 → resolved to axios@1.14.1 (malicious)
      → plain-crypto-js@4.2.1 (postinstall RAT dropper)
        → C2 callback to sfrclak.com

Why pinning doesn't help

Even if users pin this action by SHA and set datadog-ci-version to a specific version like 5.10.0, it doesn't help. The transitive dependencies are still resolved via semver ranges at runtime. There is no lockfile involved when using npx, so users have no way to protect themselves from this class of attack.

Suggested fix

Bundle the action's dependencies at build time instead of installing them at runtime. Specifically:

  1. Use @vercel/ncc (or similar) to compile @datadog/datadog-ci and all its dependencies into a single dist/index.js
  2. Change the action type from composite (with a bash npx call) to node24 (with a pre-built entry point)
  3. Check in the bundled output and a package-lock.json so that dependency versions are locked at publish time, not resolved at runtime

This is the standard approach used by most GitHub Actions (e.g., actions/checkout, actions/setup-node) and eliminates runtime dependency resolution entirely.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions