MCP is a hot protocol in the AI development industry this year, but its Client/Server (C/S) architecture requires users to run the MCP Server locally.
Common ways to run MCP Server include stdio methods like npx (NPM ecosystem), uvx (Python ecosystem), Docker, and HTTP (SSE/Streaming) methods. However, running commands with npx and uvx carries significant risks. Accidentally executing a malicious package could lead to sensitive data exposure, posing a major security threat. For details, you can refer to Invariant’s article MCP Security Notification: Tool Poisoning Attacks.
As a software industry professional, I have a high degree of concern for security. I asked ChatGPT to compile a list of NPM and PyPI supply chain attack incidents from the past 5 years, and it was chilling.
Time | Event | Summary and Scope of Impact |
---|---|---|
February 2021 | ”Dependency Confusion” Vulnerability Disclosure | Security researcher Alex Birsan utilized the Dependency Confusion technique to upload packages to NPM/PyPI with the same names as internal libraries used by multiple companies, successfully infiltrating the internal servers of 35 major companies including Apple and Microsoft (PyPI flooded with 1,275 dependency confusion packages). This demonstration sparked high concern within the industry regarding supply chain risks. |
October 2021 | UAParser.js Library Hijacked | The popular library ua-parser-js on NPM, with over 7 million weekly downloads, was compromised by attackers via the maintainer’s account to publish malicious versions (A Timeline of SSC Attacks, Curated by Sonatype). Infected versions implanted password-stealing trojans and cryptocurrency miners upon installation, affecting a large number of developer systems. |
October 2021 | Poisoning via Fake Roblox Libraries | Attackers uploaded multiple packages impersonating Roblox API on NPM (e.g., noblox.js-proxy), containing obfuscated malicious code. These packages would implant trojans and ransomware payloads after installation (A Timeline of SSC Attacks, Curated by Sonatype). These packages were downloaded thousands of times, demonstrating attackers used typosquatting to trick game developers. |
November 2021 | COA and RC Libraries Successively Hijacked | Popular libraries on NPM, coa (millions of weekly downloads) and rc (14 million weekly downloads), were successively compromised to publish malicious versions. The affected versions executed credential-stealing trojans similar to the UAParser.js case, at one point causing build pipelines to break for numerous projects globally using frameworks like React (A Timeline of SSC Attacks, Curated by Sonatype) (A Timeline of SSC Attacks, Curated by Sonatype). Official investigations determined the cause in both cases was compromised maintainer accounts. |
January 2022 | Colors/Faker Open Source Libraries “Suicide” | The authors of the famous color formatting library colors.js and test data generation library faker.js, out of protest, injected destructive code like infinite loops in the latest versions, causing thousands of projects, including those at companies like Meta (Facebook) and Amazon, to crash (A Timeline of SSC Attacks, Curated by Sonatype) (While not an external attack, it falls within the scope of supply chain poisoning). |
January 2022 | PyPI: 1,275 Malicious Packages Deployed in Bulk | A single user frantically published 1,275 malicious packages to PyPI in one day on January 23rd (A Timeline of SSC Attacks, Curated by Sonatype). Most of these packages impersonated the names of well-known projects or companies (e.g., xcryptography, Sagepay, etc.). After installation, they collected fingerprint information like hostname, IP, etc., and exfiltrated it to the attackers via DNS/HTTP (PyPI flooded with 1,275 dependency confusion packages) (PyPI flooded with 1,275 dependency confusion packages). PyPI administrators took down all related packages within an hour of receiving the report (PyPI flooded with 1,275 dependency confusion packages). |
March 2022 | Node-ipc “Protestware” Incident | The author of node-ipc, a commonly used front-end build library, added malicious code in versions v10.1.1–10.1.3: when detecting client IPs belonging to Russia or Belarus, it would wipe the file system and overwrite files with heart emojis ([Corrupted open-source software enters the Russian battlefield |
October 2022 | LofyGang Large-Scale Poisoning Campaign | Security companies discovered a group named “LofyGang” distributed nearly 200 malicious packages on NPM (LofyGang Distributed ~200 Malicious NPM Packages to Steal Credit Card Data). These packages implanted trojans through typosquatting and by impersonating common library names, stealing developers’ credit card information, Discord accounts, and game service login credentials, accumulating thousands of installations (LofyGang Distributed ~200 Malicious NPM Packages to Steal Credit Card Data). This was an organized cybercrime activity that lasted over a year. |
December 2022 | PyTorch-nightly Dependency Chain Attack | Well-known deep learning framework PyTorch disclosed that its nightly version suffered a dependency confusion supply chain attack between December 25-30 ([Malicious PyTorch dependency ‘torchtriton’ on PyPI |
March 2023 | ”W4SP Stealer” Trojan Rampant on PyPI | Security researchers successively discovered a large number of malicious packages carrying the W4SP Stealer information-stealing trojan appearing on PyPI (W4SP Stealer Discovered in Multiple PyPI Packages Under Various Names). These trojans have many aliases (e.g., ANGEL Stealer, PURE Stealer, etc.) but essentially all belong to the W4SP family, specifically designed to steal information like user passwords, cryptocurrency wallets, and Discord tokens (W4SP Stealer Discovered in Multiple PyPI Packages Under Various Names). A single report revealed 16 such malicious packages (e.g., modulesecurity, easycordey, etc.) (W4SP Stealer Discovered in Multiple PyPI Packages Under Various Names). PyPI initiated a cleanup targeting such trojans and strengthened upload detection. |
August 2023 | Lazarus Group Attacks PyPI | ReversingLabs reported that a branch of the North Korean hacking group Lazarus published over two dozen (more than 24) malicious packages disguised as popular libraries on PyPI (codenamed “VMConnect” operation) (Software Supply Chain Attacks: A (partial) History). These packages attempted to target users in specific industries (e.g., finance) to implant remote access trojans. It is claimed this attack is linked to previous similar activities targeting NuGet, showing state-sponsored hackers’ interest in the open-source supply chain. |
2024 and Beyond | Ongoing Supply Chain Threats | Since 2024, new poisoning incidents continue to emerge on NPM and PyPI. For example, in early 2024, fake VS Code-related NPM packages were found to contain remote control spyware (A Timeline of SSC Attacks, Curated by Sonatype), and PyPI packages impersonating Solana libraries to steal crypto wallet keys (A Timeline of SSC Attacks, Curated by Sonatype) were discovered. This indicates that supply chain attacks have become a normalized threat, requiring the ecosystem to continuously raise vigilance and defense capabilities. |
I complained a bit on Twitter, and while complaining, I saw a tweet from a friend who had just encountered a supply chain attack incident.
Fortunately, @TBXark recommended his MCP Proxy project, which makes it very convenient to run MCP Server in Docker. His initial goal was to run MCP Server on a server to reduce client load and facilitate mobile client calls. However, Docker’s inherent isolation features perfectly aligned with my requirement for a sandbox.
MCP Proxy runs MCP Servers in Docker and converts the protocol to MCP SSE, allowing users to make all calls via the SSE protocol from the MCP client. This can significantly reduce the risk of arbitrary file reading caused by directly running npx and uvx. If deployed on an overseas server, it can also help solve network issues.
However, it is currently still possible to read the /config/config.json
configuration file of MCP Proxy, but the risk is manageable. I have also raised a feature request with the developer to configure the config file with 400 permissions and run the npx and uvx commands as the nobody user. If this can be implemented, it will perfectly solve the arbitrary file reading issue.
Running MCP Proxy
If you have your own VPS with Docker deployed, you can use the following command to run MCP Proxy.
docker run -d -p 9090:9090 -v /path/to/config.json:/config/config.json ghcr.io/tbxark/mcp-proxy:latest
If you don’t have your own VPS, you can use the free container service provided by claw.cloud ($5 credit per month, GitHub registration must be older than 180 days).
Since Claw has container size limitations, we need to use the following environment variables to configure the cache directories for npx and uvx to prevent container crashes.
UV_CACHE_DIR=/cache/uv
npm_config_cache=/cache/npm
Simultaneously mount 10GB of storage under the /cache
path. Refer to my configuration: 0.5c CPU, 512M Memory, 10G Disk.
The final configuration is as follows:
Configuring MCP Proxy
The configuration file needs to be mounted at the /config/config.json
path. For the complete configuration, please refer to https://github.com/TBXark/mcp-proxy?tab=readme-ov-file#configurationonfiguration.
Below is my configuration, for your reference.
{
"mcpProxy": {
"baseURL": "https://mcp.miantiao.me",
"addr": ":9090",
"name": "MCP Proxy",
"version": "1.0.0",
"options": {
"panicIfInvalid": false,
"logEnabled": true,
"authTokens": [
"miantiao.me"
]
}
},
"mcpServers": {
"github": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
}
},
"fetch": {
"command": "uvx",
"args": [
"mcp-server-fetch"
]
},
"amap": {
"url": "https://mcp.amap.com/sse?key=<YOUR_TOKEN>"
}
}
}
Calling MCP proxy
Taking ChatWise calling fetch as an example, just configure the SSE protocol directly.
Isn’t it simple? When ChatWise releases its mobile version, calling it this way will also be fully usable.