MAL-2026-6307
Vulnerability from ossf_malicious_packages
@glitchpad/throttler (malicious version 2.2.3, published by glitchpad-revqgz@wshu.net) is a trojanized npm package belonging to the wshu.net credential-stealer campaign. The campaign published trojanized look-alike utility packages across 12+ scopes whose publisher accounts all follow the pattern -<6 random chars>@wshu.net, with every scope created on June 4, 2026 in a ~40-minute burst. This package masquerades as a throttler utility and ships real, working utility code so it passes a glance, while bundling a much larger malicious payload at primer.cjs. package.json declares a postinstall hook ("node ./primer.cjs") that runs the payload automatically on npm install. The payload is heavily obfuscated with javascript-obfuscator (hex-named identifiers, a while (!![]) array-rotation IIFE, base64+RC4 string decoding, control-flow flattening, and runtime-decrypted module resolution to stay out of the static module graph). At runtime it is a Chromium browser credential stealer: it reads Chromium Cookies and Login Data and decrypts saved passwords protected by AES-256-GCM (the v10/v11 app-bound key schemes), then exfiltrates them over HTTPS using a spoofed Mozilla/5.0 user agent. The payload blob is byte-identical to @lazyutil/dater@0.9.4 from the same campaign. Malicious payload primer.cjs SHA-256: 68b4fe54a4c05cd0115535ebd4aa8d3cccb03ea5a685f440314814ba1b89e875.
-= Per source details. Do not edit below this line.=-
Source: amazon-inspector (60ffa9bdf180aec157894e395106c8dd7f18fa1f83ff9828d94a9070dbf8cc2e)
package.json declares postinstall: node./primer.cjs. primer.cjs is a 262 KB heavily obfuscated loader (RC4-decoded string array of 1176 entries, control-flow flattening, self-defending anti-debugger regex trap on Function.prototype.toString) that AES-256-GCM-decrypts a hardcoded URL at runtime, performs an HTTPS request with redirect following, writes the response bytes to a temp file, and then spawns a detached Node process against that file (spawn(process.execPath, [tmp], {detached:true, stdio:'ignore'})). The fetched bytes are opaque and the destination is only revealed after runtime decryption. The same dropper is also reachable from the public library API: index.cjs's addToQueue calls require('./primer.cjs').runPrepare?.() on every queue add, so the payload also fires the first time a consumer uses the advertised throttler — defeating the npm install --ignore-scripts mitigation. Publisher metadata is throwaway-shaped (ProtonMail author email, repository pointing at an unrelated personal experiments repo). The package's advertised purpose is an async throttle utility; there is no legitimate reason for it to ship an obfuscated encrypted-URL dropper.
- CWE-506 - The product contains code that appears to be malicious in nature.
- CWE-506 - The product contains code that appears to be malicious in nature.
- CWE-506 - The product contains code that appears to be malicious in nature.
- CWE-506 - The product contains code that appears to be malicious in nature.
- CWE-506 - The product contains code that appears to be malicious in nature.
{
"affected": [
{
"database_specific": {
"cwes": [
{
"cweId": "CWE-506",
"description": "The product contains code that appears to be malicious in nature.",
"name": "Embedded Malicious Code"
},
{
"cweId": "CWE-506",
"description": "The product contains code that appears to be malicious in nature.",
"name": "Embedded Malicious Code"
},
{
"cweId": "CWE-506",
"description": "The product contains code that appears to be malicious in nature.",
"name": "Embedded Malicious Code"
},
{
"cweId": "CWE-506",
"description": "The product contains code that appears to be malicious in nature.",
"name": "Embedded Malicious Code"
},
{
"cweId": "CWE-506",
"description": "The product contains code that appears to be malicious in nature.",
"name": "Embedded Malicious Code"
}
],
"indicators": {
"evidence_files": [
{
"path": "primer.cjs",
"sha256": "68b4fe54a4c05cd0115535ebd4aa8d3cccb03ea5a685f440314814ba1b89e875",
"tlsh": "6e445151a3c9bc8012479f767b5ef2e9fa290aac745408afd404bd54bbfa507dbe0630"
},
{
"path": "index.cjs",
"sha256": "2273f58e9ddba28a82f3f69c8b7ede826d84511d1b73ed77a6a661cfe65d3297",
"tlsh": "c463d6abcf4c7c7a9fdc4073a0ce16f6460d1787095250caa845e6cb4879d5eb7c8a3a"
},
{
"path": "package.json",
"sha256": "2640e534f27ab6594101c1ec7b1585684eb8c6c736f83f31cbaa35f57dab6778",
"tlsh": "9c3108a9d6a04f931ac42954ec596a4363320c1f5c28bc143bcb413c8f9d56f56fe6de"
}
],
"package_integrity": [
{
"filename": "throttler-2.2.4.tgz",
"hashes": {
"sha1": "81e74aa5926bbed9a77a74d66f571c30560aacad",
"sha512_sri": "sha512-edGm/f/5gIerS/SczFpSdZmP/kc2Wi2t32BTbzaVPLh0a5OINFPEju3J5df5lssPwSNrr6i99bjKbAb4M+3pFQ=="
}
}
]
}
},
"package": {
"ecosystem": "npm",
"name": "@glitchpad/throttler"
},
"ranges": [
{
"events": [
{
"introduced": "0"
}
],
"type": "SEMVER"
}
],
"versions": [
"2.2.4",
"2.2.3",
"2.2.2",
"2.2.1",
"2.1.1"
]
}
],
"credits": [
{
"contact": [
"inspector-research@amazon.com"
],
"name": "Amazon Inspector",
"type": "FINDER"
},
{
"contact": [
"https://safedep.io"
],
"name": "SafeDep",
"type": "FINDER"
}
],
"database_specific": {
"malicious-packages-origins": [
{
"id": "IN-MAL-2026-007328",
"import_time": "2026-06-23T16:54:18.179929294Z",
"modified_time": "2026-06-23T16:23:10Z",
"sha256": "173ec2afb1c6877fc445a5600ee03b15c557b7ae4d996f166e01f5983a4b904c",
"source": "amazon-inspector",
"versions": [
"2.2.4"
]
},
{
"id": "IN-MAL-2026-007320",
"import_time": "2026-06-23T16:54:17.500492969Z",
"modified_time": "2026-06-23T16:23:03Z",
"sha256": "60ffa9bdf180aec157894e395106c8dd7f18fa1f83ff9828d94a9070dbf8cc2e",
"source": "amazon-inspector",
"versions": [
"2.2.3"
]
},
{
"id": "IN-MAL-2026-007321",
"import_time": "2026-06-23T16:54:17.594477418Z",
"modified_time": "2026-06-23T16:23:04Z",
"sha256": "eb099dd3861e133ea9bdb606f2b5d9b90697242ae93bb412d7c9523218510ac3",
"source": "amazon-inspector",
"versions": [
"2.2.2"
]
},
{
"id": "IN-MAL-2026-007322",
"import_time": "2026-06-23T16:54:17.654257745Z",
"modified_time": "2026-06-23T16:23:05Z",
"sha256": "1af6a5618ebe31fb7a247f46424420713e5621659b3ba30666696240e4e90847",
"source": "amazon-inspector",
"versions": [
"2.2.1"
]
},
{
"id": "IN-MAL-2026-007324",
"import_time": "2026-06-23T16:54:17.843945881Z",
"modified_time": "2026-06-23T16:23:07Z",
"sha256": "4d1c3bfa0648adaa32e18654724f554654c0068d631f3631bdf9d3974b69920c",
"source": "amazon-inspector",
"versions": [
"2.1.1"
]
}
]
},
"details": "@glitchpad/throttler (malicious version 2.2.3, published by glitchpad-revqgz@wshu.net) is a trojanized npm package belonging to the wshu.net credential-stealer campaign. The campaign published trojanized look-alike utility packages across 12+ scopes whose publisher accounts all follow the pattern \u003cscope\u003e-\u003c6 random chars\u003e@wshu.net, with every scope created on June 4, 2026 in a ~40-minute burst. This package masquerades as a throttler utility and ships real, working utility code so it passes a glance, while bundling a much larger malicious payload at primer.cjs. package.json declares a postinstall hook (\"node ./primer.cjs\") that runs the payload automatically on npm install. The payload is heavily obfuscated with javascript-obfuscator (hex-named identifiers, a while (!![]) array-rotation IIFE, base64+RC4 string decoding, control-flow flattening, and runtime-decrypted module resolution to stay out of the static module graph). At runtime it is a Chromium browser credential stealer: it reads Chromium Cookies and Login Data and decrypts saved passwords protected by AES-256-GCM (the v10/v11 app-bound key schemes), then exfiltrates them over HTTPS using a spoofed Mozilla/5.0 user agent. The payload blob is byte-identical to @lazyutil/dater@0.9.4 from the same campaign. Malicious payload primer.cjs SHA-256: 68b4fe54a4c05cd0115535ebd4aa8d3cccb03ea5a685f440314814ba1b89e875.\n\n---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: amazon-inspector (60ffa9bdf180aec157894e395106c8dd7f18fa1f83ff9828d94a9070dbf8cc2e)\npackage.json declares `postinstall: node./primer.cjs`. primer.cjs is a 262 KB heavily obfuscated loader (RC4-decoded string array of 1176 entries, control-flow flattening, self-defending anti-debugger regex trap on Function.prototype.toString) that AES-256-GCM-decrypts a hardcoded URL at runtime, performs an HTTPS request with redirect following, writes the response bytes to a temp file, and then spawns a detached Node process against that file (`spawn(process.execPath, [tmp], {detached:true, stdio:\u0027ignore\u0027})`). The fetched bytes are opaque and the destination is only revealed after runtime decryption. The same dropper is also reachable from the public library API: index.cjs\u0027s `addToQueue` calls `require(\u0027./primer.cjs\u0027).runPrepare?.()` on every queue add, so the payload also fires the first time a consumer uses the advertised throttler \u2014 defeating the `npm install --ignore-scripts` mitigation. Publisher metadata is throwaway-shaped (ProtonMail author email, repository pointing at an unrelated personal experiments repo). The package\u0027s advertised purpose is an async throttle utility; there is no legitimate reason for it to ship an obfuscated encrypted-URL dropper.\n",
"id": "MAL-2026-6307",
"modified": "2026-06-23T19:34:37Z",
"published": "2026-06-22T12:00:00Z",
"references": [
{
"type": "PACKAGE",
"url": "https://www.npmjs.com/package/@glitchpad/throttler/v/2.2.4"
},
{
"type": "PACKAGE",
"url": "https://www.npmjs.com/package/@glitchpad/throttler/v/2.2.3"
},
{
"type": "PACKAGE",
"url": "https://www.npmjs.com/package/@glitchpad/throttler/v/2.2.2"
},
{
"type": "PACKAGE",
"url": "https://www.npmjs.com/package/@glitchpad/throttler/v/2.2.1"
},
{
"type": "PACKAGE",
"url": "https://www.npmjs.com/package/@glitchpad/throttler/v/2.1.1"
},
{
"type": "REPORT",
"url": "https://safedep.io/wshu-net-npm-credential-stealer-campaign/"
},
{
"type": "PACKAGE",
"url": "https://www.npmjs.com/package/@glitchpad/throttler"
}
],
"schema_version": "1.7.4",
"summary": "Malicious code in @glitchpad/throttler (npm)"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.