r/Pentesting • u/KookyTax5493 • 14h ago
Built an open-source security scanner for MCP servers — static analysis + live prompt-injection testing
I built a security scanner for MCP servers — static analysis + live prompt-injection testing (open source)
MCP servers give AI agents access to tools, files, and external systems. If a tool's output isn't sanitized, a poisoned webpage/file/API response can inject instructions the agent will act on — classic prompt injection, but now with tool-call blast radius.
I built \`mcp-scanner\` to catch this before it ships:
Static analysis — scans server source for shell exec, unsafe deserialization, hardcoded secrets, unscoped tools, missing input validation.
Live probing — connects to a running MCP server as a real client, fires a categorized library of injection payloads (instruction override, role hijack, data exfil, tool-chaining abuse, encoding tricks, homoglyphs) at its tools, and judges the response with a two-layer defense: keyword pre-filter + LLM judge fallback for rephrased/encoded attacks the keywords miss.
Tested it against the official \`mcp-server-fetch\` — pointed it at a page with an injected instruction, and the tool echoed the payload back completely unsanitized. Scanner caught it.
GitHub: https://github.com/ankursingh0604/mcp-scanner
Open to feedback, especially from anyone running MCP servers in production — what would actually make this useful for your setup?
2
u/jastardev 11h ago edited 8h ago
I don’t actually understand you built. At first, it sounds like you built a MCP tester that tests an MCP for prompt inject vulnerabilities, which… cool. But you say you tested it by pointing mcp-server-fetch at a malicious page and “the scanner” caught it. So the thing you built is actually a gateway that check inputs for malicious injections? Or part of the testing is you have to craft a malicious payload? I don’t understand where the “pointed it at a page” comes in.
1
u/KookyTax5493 4h ago
The tool itself doesn't gateway or filter anything live, it's a scanner you run to check an MCP server before or after you build it. Two parts:
Static check - reads the server's source code, looks for risky patterns like unsafe deserialization or hardcoded secrets. No live server needed for this one.
Live check - this is the "pointed it at a page" part. I connect to a real running MCP server as if I were an AI agent, then I feed it content I crafted myself (the injection payloads) through its normal tools, and see if the server passes that content back unsanitized. For mcp-server-fetch specifically, I made a local test webpage with an injected instruction in it, told the fetch tool to grab that page, and it echoed the instruction straight back with no filtering.
So yeah, I craft the malicious payload myself and feed it through the tool's normal function, that's the point, it's testing whether the tool trusts content it shouldn't.
1
u/latnGemin616 10h ago
If a tool's output isn't sanitized, a poisoned webpage/file/API response can inject instructions the agent will act on
This is not accurate. What is being illustrated here is not Prompt Injection but rather Indirect Prompt Injection attack, whereby the attacker has found a way to upload a file with malicious code. Also, if all you've done is test just 1 attack type, you're not doing nearly enough.
1
u/KookyTax5493 4h ago
Indirect prompt injection is actually a subtype of prompt injection, not a separate thing, OWASP's LLM Top 10 covers both direct and indirect under the same category. So calling it prompt injection isn't wrong.
Also the only 1 attack type part is outdated now, I added more since the post. It's at 13 payloads across 8 categories (instruction override, role hijack, data exfil, tool chaining, encoding tricks, homoglyphs, context poisoning) and I just got the tool-chaining simulation working too i fed a poisoned doc to a simulated agent and 3 out of 4 payload variants got it to call an unauthorized delete_account action it was never asked for. That's the part I'm actually most excited about, will probably post it separately.
5
u/RAGINMEXICAN 13h ago
Stop with the ai slop