-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Proposal: Simplify wasi-tls for Security and Forward Compatibility
Executive Summary
This proposal recommends simplifying the wasi-tls API by:
- Supporting TLS 1.3 only (no TLS 1.2 fallback)
- Omitting session resumption (security over marginal performance)
- Excluding 0-RTT/early data (fundamental replay vulnerability)
- Removing suspension points (natural async evolution for Preview 3)
These changes would reduce the API surface by ~40%, eliminate entire classes of vulnerabilities, and ensure seamless evolution to WASI Preview 3's async model.
Background
The wasi-tls proposal is currently in Phase 1 and aims to provide high-level TLS functionality for WASI applications. As we move toward Phase 2, we have an opportunity to learn from industry experience and security research to create a more secure, maintainable API.
Rationale for Changes
1. TLS 1.3 Only
Current State of TLS Adoption:
- 75.3% of top websites support TLS 1.3 (SSL Labs SSL Pulse, June 2025)
- All major browsers have supported TLS 1.3 since 2018
- All major cloud providers default to TLS 1.3
Security Benefits:
- Eliminates protocol downgrade attacks entirely
- Removes weak cipher suites (RC4, 3DES, SHA-1)
- Mandatory perfect forward secrecy
- 1-RTT handshake reduces attack window
Compatibility Impact:
- Systems requiring TLS 1.2 are typically 5+ years old
- Can use TLS termination proxies if needed
- Aligns with industry deprecation timeline (many dropping TLS 1.2 in 2025)
With 75.3% adoption already achieved and growing, TLS 1.3 has reached critical mass for becoming the baseline standard.
2. Omit Session Resumption
Security Concerns:
- Weakens forward secrecy by linking multiple connections
- Complex key rotation requirements across distributed systems
- Session ticket compromise affects all linked sessions
Limited Performance Benefit with TLS 1.3:
- New connection: 1-RTT (~50-100ms)
- With resumption: 1-RTT (same RTT, minor CPU savings)
- Modern hardware makes CPU difference negligible (~2-5ms)
Recommendation: Can be added in a future version if real-world usage demonstrates need.
3. Exclude 0-RTT/Early Data
Critical Security Flaw - RFC 8446 Section 8.3:
"TLS does not provide any mechanism for guaranteeing that the early data is not replayed."
Industry Rejection:
- Cloudflare: Disabled by default
- Chrome: Not used for third-party sites
- Safari: Completely disabled
- Mozilla: Restricted to safe methods only
Attack Scenario:
1. Attacker captures 0-RTT: "POST /api/transfer?amount=1000"
2. Attacker replays packet multiple times
3. Server processes all replays (no replay protection)
4. Catastrophic consequences
4. Remove Suspension Points
Current Complexity:
// Complex state machine with suspension
flags server-suspension-points {
client-hello,
verify-client-identity,
accepted,
}
// Multiple pause/resume states = deadlock potentialSimpler Alternative:
// Linear flow without suspension
resource server {
new: static func(input, output) -> server;
set-identity: func(identity) -> result;
finish: func() -> result<connection>;
}Proposed API Design
Core Principles
- Security by default: No weak options available
- Minimal surface: Essential features only
- Forward compatible: Natural evolution to async
- Type safe: Clear resource lifecycles
Simplified WIT Interface
package wasi:tls@0.1.0;
interface tls {
use wasi:io/streams@0.2.0.{input-stream, output-stream};
use wasi:io/poll@0.2.0.{pollable};
/// TLS 1.3 only - no protocol version negotiation needed
type cipher-suite = u16; // Only AEAD suites
/// Minimal error types
enum error-code {
handshake-failure,
certificate-invalid,
certificate-untrusted,
certificate-expired,
hostname-mismatch,
internal-error,
would-block,
}
/// Certificate for validation
resource certificate {
subject: func() -> string;
issuer: func() -> string;
verify-hostname: func(hostname: string) -> bool;
}
/// Private identity (certificate + key)
resource private-identity {
certificate: func() -> certificate;
}
/// Active connection
resource connection {
cipher-suite: func() -> cipher-suite;
peer-certificate: func() -> option<certificate>;
close: func() -> result<_, error-code>;
}
/// Client handshake
resource client {
new: static func(
server-name: string,
transport-input: input-stream,
transport-output: output-stream,
) -> result<client, error-code>;
set-alpn-protocols: func(protocols: list<string>) -> result;
set-identity: func(identity: borrow<private-identity>) -> result;
finish: func() -> result<client-result, error-code>;
subscribe: func() -> pollable; // Preview 2
// finish: async func() -> result<client-result>; // Preview 3
}
record client-result {
connection: connection,
input: input-stream,
output: output-stream,
}
/// Server handshake
resource server {
new: static func(
transport-input: input-stream,
transport-output: output-stream,
) -> result<server, error-code>;
set-identity: func(identity: borrow<private-identity>) -> result;
set-alpn-protocols: func(protocols: list<string>) -> result;
set-client-auth-required: func(required: bool) -> result;
finish: func() -> result<server-result, error-code>;
subscribe: func() -> pollable; // Preview 2
// finish: async func() -> result<server-result>; // Preview 3
}
record server-result {
connection: connection,
input: input-stream,
output: output-stream,
}
}WASI Preview 3 Compatibility
The design naturally evolves to async without breaking changes:
Preview 2 (Current):
let client = Client::new(server_name, input, output)?;
let pollable = client.subscribe();
poll::wait(&[pollable])?;
let result = client.finish()?;Preview 3 (Future):
let client = Client::new(server_name, input, output)?;
let result = client.finish().await?; // Natural async/awaitNo suspension points needed - the async runtime handles waiting naturally.
Implementation Considerations
For Advanced Use Cases
If specific advanced features are needed, they can be added as separate, optional interfaces:
// Optional: SNI inspection without full handshake
interface tls-sni-inspector {
peek-sni: func(stream: input-stream) -> result<string>;
}
// Optional: Post-handshake authentication (RFC 8446 §4.6.2)
interface tls-post-handshake {
request-client-cert: func(conn: connection) -> result<certificate>;
}Migration Path for Existing Systems
For systems requiring TLS 1.2:
- Use edge/proxy for TLS termination
- Upgrade to TLS 1.3 (OpenSSL 1.1.1+ available since 2018)
- Use platform-specific TLS if legacy support required
Benefits Summary
Security Benefits
- Eliminates replay attacks (no 0-RTT)
- Prevents downgrade attacks (TLS 1.3 only)
- Improves forward secrecy (no session linkage)
- Reduces attack surface (~40% fewer code paths)
Simplicity Benefits
- ~25 methods instead of ~50+
- Linear control flow (no state machines)
- Clear error handling (no suspension edge cases)
- Easier testing (fewer state combinations)
Compatibility Benefits
- Natural Preview 3 evolution (just add
async) - No breaking changes needed for async
- Aligns with modern platforms (Lambda, Workers, etc.)
Stakeholder Alignment
This proposal aligns with:
- WASI Principles: "Start as MVP with bare minimum APIs"
- Security Best Practices: Following Cloudflare, Google, Mozilla decisions
- Industry Direction: TLS 1.2 deprecation timeline
- .NET Requirements: Works with System.Net.Security.SslStream model
Next Steps
- Gather feedback on this simplified approach
- Update imports.md with the simplified WIT
- Create reference implementation demonstrating the API
- Document security rationale for omitted features
Conclusion
By focusing on TLS 1.3's core security benefits and omitting problematic features, we can deliver a wasi-tls API that is:
- More secure (no replay vulnerabilities)
- Simpler to implement (40% less code)
- Easier to use (linear API flow)
- Future-proof (natural async evolution)
The small trade-off in compatibility (affecting only 5+ year old systems) is worth the significant gains in security and maintainability.
References
- [RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3](https://datatracker.ietf.org/doc/html/rfc8446) (August 2018)
- [SSL Labs SSL Pulse](https://www.ssllabs.com/ssl-pulse/) - Shows 75.3% TLS 1.3 adoption as of June 2025
- [Security Review of TLS 1.3 0-RTT](Security Review of TLS1.3 0-RTT tlswg/tls13-spec#1001) - Detailed analysis of 0-RTT replay vulnerabilities
- [Mozilla Security Blog: TLS 1.3 Published](https://blog.mozilla.org/security/2018/08/13/tls-1-3-published-in-firefox-today/) (August 2018)
- [Mozilla Developer Network: Transport Layer Security](https://developer.mozilla.org/en-US/docs/Web/Security/Transport_Layer_Security) - TLS 1.3 security considerations
- [SSL Labs TLS Deployment Best Practices](https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices) - Industry guidelines
- [IETF: TLS 1.3 One Year Later](https://www.ietf.org/blog/tls13-adoption/) - Adoption statistics and analysis
This proposal is submitted for discussion as wasi-tls moves toward Phase 2.