# Show HN: We scanned 23 public MCP servers for CVEs - Here is what broke

> Source: <https://dev.to/neoninnovationlab/show-hn-we-scanned-23-public-mcp-servers-for-cves-here-is-what-broke-f1l>
> Published: 2026-09-04 11:21:33+00:00

With tens of thousands of Model Context Protocol (MCP) servers published in 2026, AI agents now have direct execution bridges to local terminals, filesystems, and production databases.

Following 30+ CVE disclosures against MCP tools in early 2026 alone (including CVSS 9.4+ RCEs), verifying the security of MCP servers before plugging them into Claude Desktop, Cursor, or autonomous agent runtimes has become critical.

However, existing scanning approaches suffer from two fatal flaws:

`stdio`

commands directly from target configuration files to retrieve tool descriptions. If you scan an untrusted third-party server, you are executing arbitrary remote code on your own machine.`test/`

folders.To see what real-world security looks like, we built a zero-execution AST static auditor and benchmarked **23 prominent reference and community MCP servers**.

Here is what we found.

We evaluated 23 MCP implementations across three tiers:

`modelcontextprotocol/servers`

)`modelcontextprotocol/servers-archived`

)`fastmcp`

, `slack-mcp-server`

, `brave-search-mcp`

)| # | Target MCP Server | Files Scanned | Trust Score | Grade | Flaws Found |
|---|---|---|---|---|---|
| 1–7 |
Anthropic Core Reference (`filesystem` , `fetch` , `git` , `memory` , `sequentialthinking` , `time` ) |
~60 | `100/100` |
A+ |
0 |
| 8 |
Anthropic Reference (`everything` ) |
41 | `85/100` |
A |
1 (Unauthenticated SSE) |
| 9–20 |
Archived Reference Servers (`sqlite` , `postgres` , `slack` , `puppeteer` , `github` , `gitlab` , `redis` , `sentry` , `gdrive` ) |
~60 | `100/100` |
A+ |
0 |
| 21 | FastMCP (Community) |
491 | `25/100` |
F |
4 (ZipSlip, 0.0.0.0 SSE, Unconstrained file tools) |
| 22 | Slack MCP Server |
9 | `100/100` |
A+ |
0 |
| 23 | Brave Search MCP |
67 | `100/100` |
A+ |
0 |

In community telemetry handling, archive extraction was performed using `tarfile.extractall()`

without safe directory containment or filter flags. In Python environments, unvalidated archive members can write arbitrary files outside the destination directory when unpacked.

`filter='data'`

in Python 3.12+ or sanitize archive member paths before extracting.`0.0.0.0`

(CWE-306)
Multiple example scripts and server entrypoints bound Server-Sent Events (SSE) transports directly to `0.0.0.0`

with no authentication middleware or Bearer token checks.

`127.0.0.1`

for local usage, and require Bearer token or OAuth authentication headers whenever binding to `0.0.0.0`

.We observed tools with functions named `read_file`

or `search_files`

that accept dynamic file path parameters from LLMs and pass them directly to `open()`

without checking if the target path resides within an allowed root.

`../../etc/passwd`

).

```
target = (ALLOWED_ROOT / user_path).resolve()
if not target.is_relative_to(ALLOWED_ROOT):
    raise PermissionError("Path traversal attempt detected")
```

`subprocess.run(shell=True)`

and `child_process.exec()`

. Always pass arguments as explicit string arrays.If you maintain an MCP server or use them in production, you can test your repository for these exact vulnerabilities without running untrusted code on your machine:

👉 [MCP Security & Vulnerability Auditor on Apify Store](https://apify.com/neon_innovation_lab/mcp-security-auditor)

Drop in your public GitHub repository URL, and it generates a complete Trust Score (0–100) and actionable remediation report.
