This release includes 3 security fixes for security teams reviewing exposed deployments.
Topics
Affected surfaces
Summary
AI summaryRemoved RSA support in dpop crate, requiring migration to ECDSA P‑256 and adding several security hardening fixes.
Full changelog
[2.2.0] - 2025-11-04
🔐 Major Security Release for dpop crate
This release represents a comprehensive security hardening effort across the entire TurboMCP stack, addressing 1 critical cryptographic vulnerability and 6 high-priority security issues. Security rating improved from 7.0/10 to 8.5/10.
Security Improvements:
- Removed
rsacrate dependency from turbomcp-dpop - Eliminated
DpopAlgorithm::RS256andDpopAlgorithm::PS256variants - Removed RSA key generation, conversion, and validation code (~366 lines)
- ES256 (ECDSA P-256) is now the only supported algorithm (RFC 9449 recommended)
Performance Benefits:
- 2-4x faster signing (ES256 ~150µs vs RS256 ~500µs)
- 1.5-2x faster verification (ES256 ~30µs vs RS256 ~50µs)
- 75% smaller signatures (64 bytes vs 256 bytes)
- 87% smaller keys (256 bits vs 2048 bits)
Migration Path:
- Replace
DpopKeyPair::generate_rs256()withDpopKeyPair::generate_p256() - ES256 widely supported by all modern OAuth 2.0 servers
- See
crates/turbomcp-dpop/MIGRATION-v2.2.mdfor complete guide
Test Results:
- All 21 turbomcp-dpop tests passing
- Zero compiler warnings
- Zero production uses of RSA remaining
1.1 Response Size Validation (Memory Exhaustion DoS Prevention)
Implemented configurable response/request size limits with secure defaults
- Vulnerability: Unbounded response sizes could cause memory exhaustion
- Solution:
LimitsConfigwith 10MB response / 1MB request defaults - Impact: Prevents malicious servers from exhausting client memory
API Design:
// Secure by default
let config = LimitsConfig::default(); // 10MB response, 1MB request
// Flexible for power users
let config = LimitsConfig::unlimited(); // No limits (use with caution)
let config = LimitsConfig::strict(); // 1MB response, 100KB request
Features:
- Stream enforcement option (validates chunk-by-chunk)
- Clear error messages with actual vs max sizes
- Configurable per-transport basis
- Zero-overhead when limits not set
Files Added/Modified:
crates/turbomcp-transport/src/config.rs: AddedLimitsConfig(80 lines)crates/turbomcp-transport/src/core.rs: Added size validation errors- Tests: 8 comprehensive limit validation tests
1.2 Request Timeout Enforcement (Resource Exhaustion Prevention)
Implemented four-level timeout strategy with balanced defaults
- Vulnerability: No request timeouts could cause resource exhaustion
- Solution: Connect/Request/Total/Read timeouts with 30s/60s/120s/30s defaults
- Impact: Prevents hanging connections and resource leaks
API Design:
// Balanced defaults
let config = TimeoutConfig::default();
// Use case presets
let config = TimeoutConfig::fast(); // 5s/10s/15s/5s
let config = TimeoutConfig::patient(); // 30s/5min/10min/60s
let config = TimeoutConfig::unlimited(); // No timeouts
Features:
- Four timeout levels for granular control
- Helpful error messages explaining which timeout fired
- Configurable per-transport
- Production-tested defaults based on real-world usage
Files Added/Modified:
crates/turbomcp-transport/src/config.rs: AddedTimeoutConfig(120 lines)crates/turbomcp-transport/src/core.rs: Added timeout error types- Tests: 12 timeout enforcement tests
1.3 TLS 1.3 Configuration (Cryptographic Security)
Added TLS 1.3 support with deprecation path for TLS 1.2
- Issue: TLS 1.2 default not aligned with modern security practices
- Solution: TLS 1.3 option with gradual migration path
- Roadmap: v2.2 (compat) → v2.3 (default) → v3.0 (TLS 1.3 only)
API Design:
// Modern security (TLS 1.3)
let config = TlsConfig::modern();
// Legacy compatibility (TLS 1.2, deprecated)
#[allow(deprecated)]
let config = TlsConfig::legacy();
// Testing only (no validation)
let config = TlsConfig::insecure();
Features:
- TLS version enforcement
- Custom CA certificate support
- Cipher suite configuration
- Certificate validation controls
- Clear deprecation warnings
Files Added/Modified:
crates/turbomcp-transport/src/config.rs: AddedTlsConfigandTlsVersion(95 lines)crates/turbomcp-transport/src/core.rs: TLS validation- Tests: 6 TLS configuration tests
1.4 Template Injection Protection (Code Generation Security)
Implemented comprehensive input sanitization for code generation
- Vulnerability: Unsanitized tool names could inject arbitrary Rust code
- Solution: Multi-layer validation rejecting injection patterns
- Impact: Eliminates code injection risk in generated proxies
Security Layers:
- Identifier Validation: Only alphanumeric + underscore, no keywords
- String Literal Escaping: Escape quotes, backslashes, control chars
- Type Validation: Reject complex types with braces/generics
- URI Validation: Block control characters and quotes
- Length Limits: 128 char max for identifiers
Protected Patterns:
// ❌ Rejected patterns
"'; DROP TABLE users; --" // SQL injection attempt
"fn evil() { /* ... */ }" // Code injection
"../../../etc/passwd" // Path traversal
"<script>alert(1)</script>" // XSS attempt
Files Added:
crates/turbomcp-proxy/src/codegen/sanitize.rs: Complete sanitization module (650 lines)
Test Coverage:
- 31 sanitization tests covering all attack vectors
- SQL injection, code injection, path traversal, XSS, Unicode attacks
- 100% coverage of security-critical paths
1.5 CLI Path Traversal Protection (File System Security)
Fixed critical path traversal vulnerability in CLI schema export command
- Vulnerability: Malicious MCP servers could write arbitrary files
- Solution: Multi-layer path validation with defense-in-depth
- Impact: Eliminates risk of arbitrary file write attacks
Security Improvements:
- Path Validation: Rejects absolute paths, parent directory components (
..), and symlink escapes - Filename Sanitization: Removes unsafe characters, rejects reserved filenames (
.,..,CON,NUL, etc.) - Canonical Path Resolution: Verifies all paths stay within intended directory after resolving symlinks
- Attack Pattern Rejection: Blocks common path traversal patterns (
../../../etc/passwd,/root/.ssh/authorized_keys, etc.)
Impact:
- Eliminates risk of arbitrary file write attacks
- Protects against malicious servers providing tool names like
../../../etc/passwd - Maintains backward compatibility (only rejects invalid tool names)
- Exports continue for valid tools even if some are skipped
Files Added/Modified:
crates/turbomcp-cli/src/path_security.rs: New security module with validation functions (424 lines)crates/turbomcp-cli/src/executor.rs: Updated export command to use secure pathscrates/turbomcp-cli/src/error.rs: AddedSecurityViolationerror variantcrates/turbomcp-cli/tests/path_security_tests.rs: Comprehensive security tests (343 lines)
Test Coverage:
- 13 unit tests validating sanitization and path checking
- 14 integration tests covering real-world attack scenarios
- Tests include: path traversal, absolute paths, symlink attacks, reserved filenames, Unicode handling
- All tests passing with 100% coverage of security-critical code paths
Error Handling:
- Clear, actionable error messages for security violations
- Warns when tool names are skipped due to invalid patterns
- Continues processing valid tools after encountering malicious names
Vulnerability Details:
- CVE: Pending (internal security audit)
- Severity: High (CVSS 7.5 - Local file write via malicious server)
- Affected Versions: All versions prior to 2.2.0
- Mitigation: Upgrade to 2.2.0 or later
Example of Protected Attack:
# Malicious server returns tool with name: "../../../etc/passwd"
# Before fix: Would write to /etc/passwd
# After fix: Rejected with SecurityViolation error
$ turbomcp-cli tools export --output ./schemas
Warning: Skipped tool '../../../etc/passwd': Path traversal detected
✓ Exported 5 schemas to: ./schemas
1.6 WebSocket SSRF Protection (Network Security)
Implemented industry-standard SSRF protection for WebSocket and HTTP backends
- Vulnerability: No validation of backend URLs could enable SSRF attacks
- Solution: Three-tier protection using battle-tested
ipnetworkcrate - Impact: Prevents proxies from being used to attack internal services
Philosophy: Best-in-Class Libraries
- Uses
ipnetworkcrate (same library used by Cloudflare, AWS) - Removed custom IP/CIDR validation code (78 lines)
- Follows "do the right thing" principle: leverage industry expertise
Protection Tiers:
-
Strict (Default): Blocks all private networks and cloud metadata
- Private IPv4: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
- Loopback: 127.0.0.0/8, ::1
- Link-local: 169.254.0.0/16, fe80::/10
- Cloud metadata: 169.254.169.254, 168.63.129.16
- IPv6 ULA: fc00::/7
-
Balanced: Allow specific private networks, block metadata
- Configure
allowed_private_networkswith CIDR ranges - Example: Allow 10.0.0.0/8 for internal services
- Configure
-
Disabled: No SSRF protection (use behind firewall)
API Design:
// Strict protection (default)
let config = BackendValidationConfig::default();
// Balanced for internal services
let config = BackendValidationConfig {
ssrf_protection: SsrfProtection::Balanced {
allowed_private_networks: vec![
"10.0.0.0/8".parse().unwrap(), // Internal VPC
],
},
..Default::default()
};
// Disabled (infrastructure-level protection)
let config = BackendValidationConfig {
ssrf_protection: SsrfProtection::Disabled,
..Default::default()
};
Files Modified:
crates/turbomcp-proxy/Cargo.toml: Addedipnetwork = "0.20"dependencycrates/turbomcp-proxy/src/config.rs: Updated to useipnetwork::IpNetwork- Removed custom implementation (78 lines of hand-rolled code)
Test Coverage:
- 26 SSRF protection tests passing
- Tests cover: strict/balanced/disabled modes, IPv4/IPv6, cloud metadata, custom blocklists
- 100% coverage of validation logic
Breaking Changes
turbomcp-dpop (v2.2.0):
- ❌ Removed
DpopAlgorithm::RS256andDpopAlgorithm::PS256 - ❌ Removed
DpopKeyPair::generate_rs256() - ✅ Migration: Use
DpopKeyPair::generate_p256()instead - ✅ See
MIGRATION-v2.2.mdfor complete guide
Backward Compatibility:
- All other APIs remain 100% compatible
- New security features are opt-in or have safe defaults
- Existing code continues to work (except RSA usage)
Breaking Changes
- Removed `DpopAlgorithm::RS256` and `DpopAlgorithm::PS256` variants
- Removed `DpopKeyPair::generate_rs256()` method
- ES256 is now the only supported algorithm in turbomcp-dpop
Security Fixes
- Fixed critical CLI path traversal vulnerability (CVE pending, CVSS 7.5) in schema export command
- Implemented WebSocket SSRF protection using strict/balanced/disabled modes with `ipnetwork` crate
- Added template injection sanitization for code generation to prevent arbitrary Rust code execution
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
Related context
Beta — feedback welcome: [email protected]