Skip to content

mcp_setup_generator must restrict MCP gateway payload directory permissions — world-readable 0755 path exposes bearer token as d [Content truncated due to length] #31704

Description

@szabta89

Summary

mcp_setup_generator.go generates mkdir -p "\$\{MCP_GATEWAY_PAYLOAD_DIR}" for /tmp/gh-aw/mcp-payloads/ with no subsequent chmod, resulting in world-readable 0755 permissions. The MCP gateway container then mounts this path and creates a session subdirectory named after the full bearer token, making the token recoverable by any process on the runner host via a simple ls /tmp/gh-aw/mcp-payloads/ — no runner user identity required. This bypasses the intentional 0600 restriction on mcp-servers.json (hardened by prior fixes #1532, #1548, #1502) by leaking the same token through a different, unprotected filesystem path.

Affected Area

MCP gateway token confidentiality boundary — pkg/workflow/mcp_setup_generator.go (directory creation and permission setup for /tmp/gh-aw/mcp-payloads/); secondary concern in the MCP gateway container (ghcr.io/github/gh-aw-mcpg) which uses the raw token as the session directory name.

Reproduction Outline

  1. Run any gh-aw workflow that uses the MCP gateway (e.g., Claude Code engine), gh-aw v0.68.3.
  2. Wait approximately 90 seconds for the MCP gateway to process its first authenticated request.
  3. From any process on the runner host (any user identity — runner user NOT required), run:
    ls /tmp/gh-aw/mcp-payloads/
  4. The output is the full bearer token as a subdirectory name.
  5. Use the token directly for MCP gateway calls:
    TOKEN=$(ls /tmp/gh-aw/mcp-payloads/)
    curl -s -X POST <mcp-gateway-endpoint> \
      -H "Authorization: $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"x","version":"1"}}}'

Observed Behavior

/tmp/gh-aw/mcp-payloads/ is mode 0755 (world-readable). The gateway container (running as root) creates a subdirectory named after the full bearer token with mode 0755. The token is visible to any user on the host from a directory listing.

Expected Behavior

The mcp-payloads/ directory and its parent should be mode 0700 (runner-user-only), consistent with the intent behind mcp-servers.json being 0600. Additionally, the MCP gateway should use a hash or ephemeral random session ID as the directory name so the bearer token never appears as a filesystem path component.

Security Relevance

The bearer token controls access to create_issue, noop, and other safe-outputs write-sink tools via the MCP gateway. Recovery requires only a directory listing on a world-accessible path — no runner user identity, no special privileges. This is distinct from the runner-user-only risk in #25102 (upstream of githubnext/gh-aw-security#1695): that finding required the runner identity to read a 0600 file; this finding requires no special identity at all. Risk is highest on self-hosted or shared runners where other user identities (containers, services, tool processes) coexist on the host.

Suggested Fix

Immediate (smallest fix): Add chmod 700 "\$\{MCP_GATEWAY_PAYLOAD_DIR}" after the mkdir -p line in mcp_setup_generator.go (pkg/workflow/mcp_setup_generator.go, line ~575).

Deeper fix: Change the MCP gateway container to create session subdirectories named after a random session ID or one-way hash of the token — never the token itself — so the bearer token is never a filesystem path component.

Additional Context

If the current behavior (bearer token as directory name in a world-accessible path) is considered an acceptable operational assumption, that assumption should be explicitly documented in the security model. As-is, it contradicts the documented intent of the 0600 restriction on mcp-servers.json.

gh-aw version: v0.68.3 (from compiler_version in lock file)

Original finding: https://github.com/githubnext/gh-aw-security/issues/2125

Generated by File Issue · ● 244.5K ·

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions