Skip to content

Unauthenticated exposure probes reuse authenticated transport state #1

Description

@sanjayy0612

Bug

REAP’s unauthenticated-exposure probes reuse the session that was initialized with --auth-header.

probe.WithNoAuth() only suppresses a per-request Authorization header. It does not establish a separate anonymous transport/session. As a result, REAP can report authenticated access as unauthenticated exposure.

Confirmed WebSocket case

This is directly reproducible for the WebSocket transport:

  1. Run REAP against an MCP endpoint over WebSocket with --auth-header.

  2. The WebSocket upgrade succeeds using those credentials.

  3. mcp-unauth-tools-list calls:

    s.Do(ctx, "tools/list", map[string]any{}, probe.WithNoAuth())
  4. In WSSession.Do(), request options—including WithNoAuth()—are intentionally ignored because authentication is established during the WebSocket handshake.

  5. If tools/list succeeds, REAP can report that the tool list is accessible without authentication, even though the connection was authenticated.

Affected probes

  • mcp-unauth-tools-list
  • mcp-resources-prompts-exposure
  • OAuth Bearer-challenge detection, which also issues tools/list with WithNoAuth()

Related transport state

The same approach may also be unsafe for other transports:

  • Streamable HTTP retains Mcp-Session-Id captured during authenticated initialization.
  • Legacy HTTP+SSE retains an authenticated long-lived SSE connection.

Expected behavior

A finding described as “unauthenticated” should be based on a separate anonymous connection/session, without credentials or state established by an authenticated connection.

Actual behavior

On WebSocket, WithNoAuth() cannot make a request anonymous after an authenticated upgrade. The scanner may emit false high-confidence unauthenticated-exposure findings.

Suggested direction

Run authentication-sensitive probes through a separate unauthenticated session/connection, or exclude transports where an anonymous per-request request cannot be represented safely.

Regression test

Add an authentication-required WebSocket MCP test server:

  1. Require credentials during WebSocket upgrade.
  2. Return a non-empty tools/list result only on authenticated connections.
  3. Scan with --auth-header.
  4. Verify that REAP does not emit an unauthenticated-exposure finding.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions