Skip to content

Epistates/TurboMCP

v3.1.3 Security

This release includes 5 security fixes for security teams reviewing exposed deployments.

Published 27d MCP Developer Tools
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →
This release patches 5 known CVEs

Topics

mcp mcp-client mcp-sdk mcp-server mcp-servers rust

Affected surfaces

auth rbac rce_ssrf

Summary

AI summary

Strict JSON-RPC version validation rejects non-"2.0" requests.

Full changelog

[3.1.3]

Patch release: follow-on exhaustive audit of lower-to-upper layers, focusing on
JSON-RPC correctness, stream framing robustness, deprecated transport surface
removal, dependency freshness, and active documentation/scaffold alignment.

Security

  • JSON-RPC version validation is now strict on inbound core routing — requests
    whose jsonrpc member is missing or not exactly "2.0" are rejected before
    handler dispatch.
  • OpenAPI URL fetches validate before network access — URL inputs are parsed
    and SSRF-checked before the HTTP request is built, with a bounded request
    timeout.
  • Server/proxy HTTP and WebSocket frontends enforce configured limits and
    origin checks
    — HTTP request bodies honor ServerConfig.max_message_size,
    WebSocket upgrade paths validate Origin, and proxy browser frontends retain
    auth/origin enforcement after migrating off deprecated adapters.
  • DPoP replay detection now rejects duplicates before cache eviction — the
    in-memory nonce tracker checks for replay while holding the write lock, so a
    saturated cache cannot evict the duplicate before detection. Redis-backed
    duplicate nonce detection now maps to the dedicated replay error as well.
  • DPoP JWK validation rejects private key material — public JWK headers
    containing a private d member are rejected, while interoperable public EC
    JWKs that omit use are accepted as signature keys.
  • WASM streamable HTTP session headers validate without panicking — invalid
    Mcp-Session-Id headers now return 400 Bad Request instead of constructing
    unchecked session IDs.

Changed

  • Proxy frontends migrated to supported server transports — runtime and CLI
    serving paths now use turbomcp-server HTTP/WebSocket plumbing instead of the
    removed turbomcp-transport::axum compatibility layer.
  • CLI scaffolds and active docs now target current public APIs — generated
    examples use the current crate version and supported resource/tool patterns,
    and active README/migration guidance no longer points new users at deprecated
    surfaces.
  • Release-facing metadata now targets 3.1.3 — workspace manifests, internal
    crate dependency pins, lockfile entries, install snippets, README examples,
    and package-facing migration docs identify the patch release consistently.
  • Declared dependencies refreshed to latest available releases — workspace
    manifests now target current direct dependency versions, including reqwest
    0.13.3, tower-http 0.6.9, metrics 0.24.5,
    metrics-exporter-prometheus 0.18.3, serde_with 3.19, redis 1.2.1,
    signature 3.0, utoipa 5.5, wasm-bindgen 0.2.120, and
    js-sys/web-sys 0.3.97. cargo outdated --workspace --root-deps-only
    reports all direct dependencies current after the refresh.

Removed

  • Deprecated turbomcp-transport::axum subtree deleted — callers should use
    turbomcp_server::transport::http, McpServerExt::run_http, or
    McpServerExt::into_axum_router.
  • Deprecated transport and client shims removedStreamingTransport,
    TransportType::Grpc / TransportType::Quic, no-op WebSocket compression/TLS
    builders, the no-op gRPC TLS client config field, and
    turbomcp-client::sampling::ServerInfo are gone.

Fixed

  • SSE and streaming decoders handle edge framing cases — CRLF events,
    whitespace-only lines, trailing newlines, empty data: events, sticky
    overflow states, and last_event_id propagation now behave consistently.
  • SSE incremental parsing handles split UTF-8 sequences — partial multibyte
    code points are buffered across feed() calls instead of being dropped or
    corrupting subsequent events.
  • JSON-RPC error classification and capping tightenedstandard_kind()
    only reports the five JSON-RPC standard errors, while error data capping now
    recurses through arrays as well as objects.
  • JSON-RPC response payload validation is presence-awareresult: null
    is now accepted as a valid success response, while responses with both
    result and error or neither member are rejected.
  • JSON-RPC request parsing validates IDs and preserves notification
    semantics
    — inbound request IDs must be strings or integer numbers; null,
    fractional, boolean, array, and object IDs are rejected as invalid requests.
    Successful method notifications no longer produce JSON-RPC success responses,
    while parse/invalid-request errors with unknown IDs still serialize correctly.
  • params: null remains compatible with absent params — explicit JSON
    null params deserialize as None rather than a structured parameter value.
  • Spec optional fields are represented accurately — cancellation
    notifications accept missing requestId, resource subscribe/unsubscribe/update
    notifications include optional _meta, and client logging no longer assumes a
    cancellation id is always present.
  • Elicitation mode parsing is strict and URL error codes are consistent
    unknown or non-string modes now fail deserialization, and
    URLElicitationRequiredError uses the same -32042 code as the core error
    taxonomy.
  • alloc-only builds keep compiling — missing alloc imports in the
    bottom-level type crates were restored and checked under no-default-features
    configurations.
  • The transports demo is warning-free across feature sets — transport list
    construction no longer requires a mutable binding when only the base transport
    is enabled.
  • Validation utilities avoid duplicate work and retry edge cases
    validation dispatch no longer runs duplicate checks for the same value, and
    retry_with_backoff(max_attempts = 0) now performs the initial attempt.
  • Active API docs and rustdoc links align with the current public surface
    core/gRPC references no longer advertise removed imports or client methods,
    proxy README package links no longer target ignored local notes, and rustdoc
    now passes with warnings denied.
  • Examples and demo documentation match current runnable APIs — STDIO
    examples now show complete MCP initialization flows, transport examples use
    the required client features, a Unix server/client pair is documented and
    compiled, proxy schema export has a no-backend mock mode, and stale unsupported
    file-based config examples were removed.

Full Changelog: https://github.com/Epistates/turbomcp/compare/v3.1.2...v3.1.3

Breaking Changes

  • Inbound core routing now rejects JSON‑RPC requests whose `jsonrpc` member is missing or not exactly "2.0" before handler dispatch.

Security Fixes

  • JSON-RPC version validation is now strict, rejecting malformed or non-2.0 requests.
  • OpenAPI URL fetches are SSRF‑checked and bounded with a request timeout.
  • HTTP/WebSocket frontends enforce configured `max_message_size`, validate `Origin` headers, and retain auth/origin checks after transport migration.
  • DPoP replay detection rejects duplicates before cache eviction; Redis‑backed nonce tracking maps to the dedicated replay error.
  • DPoP JWK validation now rejects private key material (`d` member) while accepting interoperable public EC JWKs lacking `use`.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track Epistates/TurboMCP

Get notified when new releases ship.

Sign up free

About Epistates/TurboMCP

TurboMCP SDK: Enterprise MCP SDK in Rust

All releases →

Beta — feedback welcome: [email protected]