Assessment Date: December 5, 2025 Assessed By: Security Engineer (Claude Code) Architecture: QUIC-First Unified Protocol Handler
CRITICAL FINDING: The TypeScript API client architecture is fundamentally incompatible with the QUIC-only ZHTP backend.
The API client library is designed to use standard JavaScript fetch() API over HTTP/HTTPS, but the ZHTP backend is a QUIC-only UDP protocol (port 9334) with no HTTP server. While the backend includes an HttpCompatibilityLayer, this layer only works for HTTP-over-QUIC connections, not traditional HTTP-over-TCP.
Current Design (BROKEN):
┌─────────────────────────┐
│ TypeScript API Client │
│ fetch() → HTTP/TCP │ ❌ Cannot connect to UDP
└─────────────────────────┘
↓
(fails - protocol mismatch)
↓
┌─────────────────────────┐
│ ZHTP Backend Node │
│ QUIC/UDP port 9334 │ ← Only accepts UDP packets
│ No TCP HTTP server │
└─────────────────────────┘
Working Architecture:
┌─────────────────────────┐
│ HTTP/3 Client │
│ HTTP over QUIC (UDP) │ ✓ Can connect
└─────────────────────────┘
↓
UDP/QUIC connection
↓
┌─────────────────────────────────────┐
│ ZHTP Backend (port 9334/UDP) │
│ │
│ QuicHandler.accept_loop() │
│ ↓ Protocol Detection on Stream │
│ ├─ HTTP methods → HttpCompatLayer │
│ ├─ b"ZHTP" → ZhtpRouter │
│ └─ PQC handshake → Mesh Protocol │
└─────────────────────────────────────┘
The TypeScript API client WILL NOT WORK with the QUIC backend because:
-
JavaScript
fetch()uses HTTP/1.1 or HTTP/2 over TCP- Standard fetch() cannot connect to UDP endpoints
- QUIC requires specialized client libraries
- No browser-native HTTP/3 support in fetch() API
-
ZHTP backend has NO TCP HTTP server
- Port 9334 is UDP-only (QUIC)
- No TCP listener on any port for HTTP
- HttpCompatibilityLayer only processes HTTP-over-QUIC, not HTTP-over-TCP
-
Default URL is broken:
http://localhost:8000- Uses http:// scheme (TCP)
- Wrong port (backend is 9334, not 8000)
- Wrong protocol (HTTP/TCP vs QUIC/UDP)
From /Users/supertramp/Dev/The-Sovereign-Network/zhtp/src/unified_server.rs:
// Line 16: TCP/UDP no longer used - QUIC-only architecture
// REMOVED: TCP/UDP handlers - Replaced by QuicHandler
// Line 86-87: QUIC is ONLY ENTRY POINT
quic_mesh: Arc<QuicMeshProtocol>,
quic_handler: Arc<QuicHandler>,
// Line 249: QUIC uses port 9334 (not 9333 or 8000)
let quic_port = port + 1; // 9334
// Line 889-897: QUIC accept loop is PRIMARY protocol
tokio::spawn(async move {
info!("🚀 Starting QUIC accept loop on endpoint...");
if let Err(e) = quic_handler.accept_loop(endpoint).await {
error!("❌ QUIC accept loop terminated: {}", e);
}
});From /Users/supertramp/Dev/The-Sovereign-Network/zhtp/src/server/quic_handler.rs:
// Line 326-343: QuicHandler is SINGLE ENTRY POINT
/// THIS IS THE SINGLE ENTRY POINT - replaces QuicMeshProtocol::start_receiving()
pub async fn accept_loop(&self, endpoint: Arc<quinn::Endpoint>) -> Result<()> {
info!("🌐 QUIC unified handler started - single entry point for all protocols");
loop {
match endpoint.accept().await {
Some(incoming) => {
self.handle_connection_incoming(incoming).await?;
}
None => {
warn!("QUIC endpoint closed");
break;
}
}
}
Ok(())
}The backend does support HTTP, but ONLY over QUIC:
- Client establishes QUIC connection (UDP handshake)
- Opens bidirectional stream
- Sends HTTP request:
GET /api/v1/identity HTTP/1.1\r\n... - QuicHandler detects HTTP method in first bytes
- Routes to
HttpCompatibilityLayer - Converts HTTP → ZHTP → ZhtpRouter → API handler
- Returns ZHTP response → HTTP response over QUIC stream
This is HTTP/3 (HTTP-over-QUIC), NOT HTTP/1.1 (HTTP-over-TCP).
Original: Default URL http://localhost:8000 exposes credentials over unencrypted HTTP.
Revised Status: NOT APPLICABLE - The client cannot connect at all because:
- Backend has no HTTP server
- QUIC provides mandatory TLS 1.3 encryption
- All QUIC connections are encrypted by default
New Issue: Default URL is wrong protocol/port entirely.
Original: User-controlled URL could trigger SSRF attacks.
Revised Status: REDUCED RISK - QUIC architecture limits SSRF because:
- QUIC connections require UDP, not TCP (different attack surface)
- Post-quantum cryptography prevents MITM
- No connection pooling/reuse across domains
Remaining Risk: If gateway/proxy is added, SSRF could resurface.
Status: STILL CRITICAL
The threat model changes with QUIC:
- Good: QUIC mandates TLS 1.3, so tokens are encrypted in transit
- Bad: XSS can still steal tokens from localStorage
- New Risk: QUIC connection hijacking if token is used for authentication
Recommendation: Use httpOnly cookies or memory-only storage. If tokens are used, implement:
- Short-lived tokens (15 minutes)
- Refresh token rotation
- QUIC connection ID binding to prevent replay
Status: STILL CRITICAL
Passwords sent in JSON request bodies are visible to:
- JavaScript code (XSS exposure)
- Browser developer tools
- Logging systems
QUIC Impact: Transport encryption doesn't protect against XSS.
Recommendation: Use Credential Management API or WebAuthn.
Status: STILL HIGH
QUIC doesn't change input validation requirements.
New Concern: QUIC streams are binary - malformed requests could crash backend parser.
Status: STILL HIGH
Error disclosure risk unchanged by transport protocol.
Status: STILL RELEVANT (if browser-based)
CSRF attacks target browser behavior, not transport protocol.
QUIC Consideration: If using QUIC directly (not via fetch), CSRF is irrelevant because browsers won't send automatic requests.
Status: STILL HIGH
QUIC backend implements rate limiting at protocol level (P1-1 controls in quic_handler.rs):
// Lines 89-91 from quic_handler.rs
const MAX_HANDSHAKES_PER_IP: usize = 10;
const HANDSHAKE_RATE_WINDOW: Duration = Duration::from_secs(60);But client-side rate limiting is still needed to prevent:
- Accidental DoS from retry logic
- Credential stuffing attempts
- Account lockout
Severity: P0 (Blocks all functionality)
Issue: JavaScript fetch() API cannot establish QUIC connections.
Impact:
- API client cannot connect to backend
- All API methods will fail
- Library is non-functional
Root Cause:
// From src/core/zhtp-api-core.ts line 28
this.fetchAdapter = fetchAdapter || ((url, options) => fetch(url, options));Standard fetch() uses HTTP/1.1 or HTTP/2 over TCP, not QUIC (HTTP/3) over UDP.
How Browsers Handle HTTP/3:
- HTTP/3 (HTTP-over-QUIC) requires browser-level support
- Browsers implement QUIC internally (not exposed to JavaScript)
- fetch() MAY use HTTP/3 if:
- Server advertises HTTP/3 via Alt-Svc header
- Browser supports HTTP/3
- Prior connection exists
- But: There's no standard way to force HTTP/3 in JavaScript
Proof of Non-Functionality:
// This will FAIL:
const api = new ZhtpApi(config);
await api.testConnection();
// Because fetch() will try:
fetch('http://localhost:9334/api/v1/protocol/info')
↓
// Attempts TCP connection to port 9334
// Port 9334 is UDP (QUIC) only
// Connection refused - no TCP listenerSolutions:
-
Browser Environment:
- Impossible to force QUIC from JavaScript
- Would need browser to auto-upgrade to HTTP/3
- Requires Alt-Svc mechanism (server must advertise HTTP/3 on HTTP/2 first)
-
React Native Environment:
- Implement native QUIC client (as documented in QUIC-TRANSPORT.md)
- Use Cronet (Android) or Network.framework (iOS)
- Bridge to JavaScript via custom FetchAdapter
-
Add Gateway Layer:
- Deploy HTTP/TCP proxy that bridges to QUIC backend
- Proxy translates HTTP/TCP → HTTP/3 (QUIC)
- Loses many QUIC benefits (0-RTT, multiplexing, PQC)
Recommendation: OPTION 3 is required for browser compatibility.
Deploy a gateway service:
Browser (fetch/HTTP/1.1) → Gateway (port 8000/TCP) → ZHTP Backend (port 9334/UDP)
HTTP/1.1 QUIC/HTTP-3
Gateway responsibilities:
- Accept HTTP/1.1 connections on port 8000
- Translate to HTTP/3 (QUIC) to backend
- Handle TLS termination
- Forward responses back to HTTP/1.1
Severity: P0 (Prevents connection)
Issue: Default URL and port are wrong.
From /Users/supertramp/Dev/sovereign-network-api-client/src/vanilla-js/config-provider.ts:
// Lines 41-45 (inferred from context)
const defaults = {
zhtpNodeUrl: 'http://localhost:8000', // ❌ Wrong port
networkType: 'testnet',
debugMode: false,
enableBiometrics: false,
};Backend Reality:
- Port: 9334 (not 8000)
- Protocol: QUIC/UDP (not HTTP/TCP)
- Scheme:
quic://orhttps://(nothttp://)
Should Be:
zhtpNodeUrl: 'https://localhost:9334', // If HTTP/3 auto-upgrade works
// OR
zhtpNodeUrl: 'http://localhost:8000', // If gateway proxy existsImpact: All connection attempts fail immediately.
Severity: P1 (High)
Issue: QUIC connection migration could be exploited for hijacking.
QUIC Feature: Connection IDs allow connections to survive IP address changes (mobile networks, WiFi switching).
Attack Vector:
- Attacker observes legitimate QUIC connection
- Injects packets with same Connection ID from different IP
- Backend accepts migrated connection
- Attacker can send requests as legitimate client
Mitigation in Backend:
Backend uses post-quantum cryptography (PQC) for peer-to-peer connections:
// From unified_server.rs line 165
// Post-Quantum Cryptography: Kyber512 + Dilithium2 for mesh connectionsBut client-to-server connections (HTTP compatibility layer) may not use PQC.
Recommendation:
- Verify HttpCompatibilityLayer validates connection authenticity
- Implement connection ID validation with cryptographic binding
- Use TLS 1.3 session resumption tokens for migration validation
Severity: P1 (High)
Issue: Protocol detection on stream-level could be exploited.
From /Users/supertramp/Dev/The-Sovereign-Network/zhtp/src/server/quic_handler.rs:
// Line 387-430: Protocol detection on first stream
match protocol {
ProtocolType::PqcHandshake(initial_data) => { /* mesh peer */ }
ProtocolType::NativeZhtp(initial_data) => { /* API request */ }
ProtocolType::LegacyHttp(initial_data) => { /* HTTP compat */ }
ProtocolType::MeshMessage(initial_data) => { /* blockchain sync */ }
ProtocolType::Unknown(initial_data) => { /* error */ }
}Attack Scenarios:
-
HTTP Request Smuggling:
- Attacker crafts request:
ZHTP\x01GET /admin HTTP/1.1\r\n... - Detected as ZHTP (first 4 bytes)
- But contains HTTP payload that might confuse router
- Attacker crafts request:
-
PQC Handshake Spoofing:
- Attacker sends fake PQC handshake to establish "peer" connection
- Gains access to mesh message routing
- Could inject malicious blockchain sync data
-
Protocol Downgrade:
- Force detection as HTTP instead of native ZHTP
- Bypass ZHTP-specific security controls
- Exploit HTTP parser vulnerabilities
Mitigation:
Backend has some protections:
// Line 74-75: Protocol detection timeout
const PROTOCOL_DETECT_TIMEOUT: Duration = Duration::from_secs(5);
// Lines 89-91: Handshake rate limiting
const MAX_HANDSHAKES_PER_IP: usize = 10;
const HANDSHAKE_RATE_WINDOW: Duration = Duration::from_secs(60);Recommendations:
- Strict protocol validation (reject ambiguous payloads)
- Cryptographic commitment to protocol choice
- Separate ports for peer-to-peer (PQC) vs client-server (HTTP)
Severity: P1 (High)
Issue: QUIC uses UDP, which is susceptible to amplification attacks.
Attack:
- Attacker spoofs victim's IP address
- Sends small QUIC request to ZHTP backend
- Backend sends large response to victim
- Victim receives unsolicited traffic (DDoS)
Standard QUIC Mitigation:
- Address validation during handshake
- Response size limits before validation
Backend Check:
Backend uses quinn library which implements QUIC RFC 9000 protections:
- 3x amplification limit before address validation
- Retry packets for validation
- Path validation challenges
Recommendation:
- Verify quinn is configured with amplification protection
- Monitor for abnormal response sizes
- Implement rate limiting on retry packets
Severity: P2 (Medium)
Issue: QUIC connection parameters leak implementation details.
Fingerprinting Vectors:
- Initial packet structure
- Connection ID format
- Supported protocol versions
- Transport parameters
- PQC algorithms used (Kyber512, Dilithium2)
Impact:
- Attacker can identify ZHTP nodes
- Targeted attacks against specific versions
- Network censorship (identify and block ZHTP traffic)
Mitigation:
- Randomize connection IDs
- Normalize transport parameters
- Use standard QUIC versions
- Consider traffic obfuscation for censorship-resistant networks
Severity: P2 (Medium)
Issue: QUIC allows multiple streams per connection - potential DoS.
Attack:
- Attacker establishes QUIC connection
- Opens hundreds of streams
- Sends partial requests on each
- Exhausts backend memory/file descriptors
Backend Protection:
// Line 66-69: Idle timeouts
const CLIENT_IDLE_TIMEOUT: Duration = Duration::from_secs(60);
const PEER_IDLE_TIMEOUT: Duration = Duration::from_secs(300);
// Line 78: Connection limit
const MAX_PQC_CONNECTIONS: usize = 10_000;Gaps:
- No per-connection stream limit mentioned
- No stream creation rate limiting
- Memory exhaustion from incomplete requests
Recommendations:
- Configure quinn
max_concurrent_bidi_streams(e.g., 100) - Implement stream creation rate limiting
- Set stream data size limits before processing
- Monitor connection stream counts
┌──────────────────────────────────────────────────────┐
│ Browser Environment │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ TypeScript API Client │ │
│ │ fetch() → HTTP/1.1 over TCP │ │
│ └────────────────────┬───────────────────────┘ │
│ │ │
└───────────────────────┼─────────────────────────────┘
│ HTTP/1.1 (port 8000/TCP)
▼
┌──────────────────────────────────────────────────────┐
│ HTTP-to-QUIC Gateway Service │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ - Accept HTTP/1.1 on port 8000/TCP │ │
│ │ - TLS termination (SSL cert for localhost) │ │
│ │ - Translate to HTTP/3 (QUIC) │ │
│ │ - Forward to ZHTP backend │ │
│ │ - Handle response conversion │ │
│ └────────────────────┬───────────────────────┘ │
│ │ │
└───────────────────────┼─────────────────────────────┘
│ HTTP/3 QUIC (port 9334/UDP)
▼
┌──────────────────────────────────────────────────────┐
│ ZHTP Backend (Rust) │
│ │
│ QuicHandler.accept_loop() on port 9334/UDP │
│ ↓ │
│ HTTP method detection │
│ ↓ │
│ HttpCompatibilityLayer │
│ ↓ │
│ ZhtpRouter → API Handlers │
└──────────────────────────────────────────────────────┘
Gateway Implementation (Example):
// gateway.ts - Node.js HTTP-to-QUIC bridge
import http from 'http';
import { Http3Client } from '@fails-components/webtransport';
const ZHTP_BACKEND = 'https://localhost:9334';
const server = http.createServer(async (req, res) => {
// Forward HTTP/1.1 request to QUIC backend
const quicClient = new Http3Client(ZHTP_BACKEND);
const response = await quicClient.fetch(req.url, {
method: req.method,
headers: req.headers,
body: req.body
});
res.writeHead(response.status, response.headers);
res.end(await response.text());
});
server.listen(8000);
console.log('HTTP-to-QUIC gateway listening on port 8000');Deployment:
# Start ZHTP backend
cd The-Sovereign-Network/zhtp
cargo run # Runs on port 9334/UDP
# Start gateway (separate process)
node gateway.js # Runs on port 8000/TCP
# API client connects to gateway
const config = new BrowserConfigProvider({
zhtpNodeUrl: 'http://localhost:8000', # Gateway, not backend
networkType: 'testnet'
});Security Considerations:
- Gateway becomes single point of failure
- TLS termination at gateway (end-to-end encryption lost)
- Gateway must validate all requests
- Rate limiting at both gateway and backend
┌──────────────────────────────────────────────────────┐
│ React Native Application │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ TypeScript API Client │ │
│ │ with custom FetchAdapter │ │
│ └────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────▼───────────────────────────┐ │
│ │ Native QUIC Bridge (Swift/Kotlin) │ │
│ │ - iOS: Network.framework QUIC │ │
│ │ - Android: Cronet (Chrome networking) │ │
│ └────────────────┬───────────────────────────┘ │
│ │ │
└───────────────────┼─────────────────────────────────┘
│ QUIC (port 9334/UDP)
│ Direct connection
▼
┌──────────────────────────────────────────────────────┐
│ ZHTP Backend (Rust) │
│ │
│ QuicHandler.accept_loop() on port 9334/UDP │
│ ↓ │
│ HTTP method detection │
│ ↓ │
│ HttpCompatibilityLayer │
│ ↓ │
│ ZhtpRouter → API Handlers │
└──────────────────────────────────────────────────────┘
Implementation (as documented in QUIC-TRANSPORT.md):
// React Native with native QUIC
import { ZhtpApi, ReactNativeConfigProvider, FetchAdapter } from '@sovereign-net/api-client/react-native';
import { NativeModules } from 'react-native';
const { QuicClient } = NativeModules;
const quicFetchAdapter: FetchAdapter = async (url, options) => {
const response = await QuicClient.request({
url,
method: options?.method || 'GET',
headers: options?.headers,
body: options?.body,
});
return {
ok: response.status >= 200 && response.status < 300,
status: response.status,
statusText: response.statusText,
headers: new Headers(response.headers),
json: async () => JSON.parse(response.body),
text: async () => response.body,
} as Response;
};
const config = new ReactNativeConfigProvider({
zhtpNodeUrl: 'quic://node.sovereignnet.io:9334', // Direct QUIC
networkType: 'mainnet'
});
const api = new ZhtpApi(config, quicFetchAdapter);Native Bridge (iOS - Swift):
import Network
@objc(QuicClient)
class QuicClient: NSObject {
@objc
func request(_ params: NSDictionary,
resolver resolve: @escaping RCTPromiseResolveBlock,
rejecter reject: @escaping RCTPromiseRejectBlock) {
let endpoint = NWEndpoint.hostPort(
host: NWEndpoint.Host(params["host"] as! String),
port: NWEndpoint.Port(integerLiteral: 9334)
)
// Use HTTP/3 over QUIC
let parameters = NWParameters.quic(alpn: ["h3"]) // HTTP/3 ALPN
parameters.allowLocalEndpointReuse = true
let connection = NWConnection(to: endpoint, using: parameters)
connection.start(queue: .global())
// Send HTTP request over QUIC stream
let httpRequest = buildHTTPRequest(params)
connection.send(
content: httpRequest,
completion: .contentProcessed { error in
if let error = error {
reject("QUIC_ERROR", error.localizedDescription, error)
}
}
)
// Receive response
connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, _, isComplete, error in
if let error = error {
reject("QUIC_ERROR", error.localizedDescription, error)
return
}
if let data = data {
let response = parseHTTPResponse(data)
resolve(response)
}
}
}
}Security Benefits:
- Direct QUIC connection (no gateway)
- Post-quantum cryptography (Kyber512 + Dilithium2)
- 0-RTT connection resumption
- Connection migration support
- Better performance
Security Risks:
- More complex native code (Swift/Kotlin attack surface)
- Certificate validation must be implemented correctly
- Connection ID management
- PQC handshake validation
┌──────────────────────────────────────────────────────┐
│ Browser Environment │
│ (Chrome 97+, Edge 97+) │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ TypeScript API Client │ │
│ │ WebTransport API (QUIC in browser) │ │
│ └────────────────────┬───────────────────────┘ │
│ │ │
└───────────────────────┼─────────────────────────────┘
│ QUIC (port 9334/UDP)
│ Direct connection
▼
┌──────────────────────────────────────────────────────┐
│ ZHTP Backend (Rust) │
│ │
│ QuicHandler.accept_loop() on port 9334/UDP │
│ ↓ │
│ WebTransport detection │
│ ↓ │
│ ZhtpRouter → API Handlers │
└──────────────────────────────────────────────────────┘
Implementation:
// Future: WebTransport-based API client
export class WebTransportZhtpClient {
private transport: WebTransport;
async connect(url: string) {
// WebTransport uses QUIC natively
this.transport = new WebTransport(`https://localhost:9334`);
await this.transport.ready;
}
async request(method: string, path: string, body?: any): Promise<any> {
const stream = await this.transport.createBidirectionalStream();
const writer = stream.writable.getWriter();
const reader = stream.readable.getReader();
// Send HTTP/3 request
const request = new TextEncoder().encode(
`${method} ${path} HTTP/3\r\n` +
`Host: localhost:9334\r\n` +
`Content-Type: application/json\r\n\r\n` +
(body ? JSON.stringify(body) : '')
);
await writer.write(request);
await writer.close();
// Read response
const { value } = await reader.read();
return JSON.parse(new TextDecoder().decode(value));
}
}Status:
- WebTransport is experimental (not widely supported)
- Requires HTTPS certificates (even for localhost)
- Backend would need WebTransport ALPN support
| ID | Issue | Impact | Solution |
|---|---|---|---|
| P0-1 | fetch() cannot connect to QUIC | Library non-functional | Deploy HTTP-to-QUIC gateway |
| P0-2 | Wrong default URL/port | Connection failures | Update to port 9334 or gateway port |
| ID | Issue | Impact | Solution |
|---|---|---|---|
| P1-1 | Session tokens in localStorage | XSS exposure, token theft | httpOnly cookies or memory storage |
| P1-2 | Credentials in request body | XSS exposure, logging leaks | Credential Management API |
| P1-6 | QUIC connection hijacking | Session takeover | Connection ID validation |
| P1-7 | Protocol confusion attacks | Bypass security controls | Strict protocol validation |
| P1-8 | UDP amplification attacks | DDoS vector | Verify quinn amplification protection |
| ID | Issue | Impact | Solution |
|---|---|---|---|
| P2-1 | No input validation | Injection attacks | Zod/Yup validation |
| P2-2 | Verbose error messages | Information disclosure | Generic error messages |
| P2-5 | No CSRF protection | Cross-site attacks | CSRF tokens (if browser-based) |
| P2-6 | No client-side rate limiting | Brute force, DoS | Request throttling |
| P2-7 | QUIC fingerprinting | Censorship, targeted attacks | Randomize connection params |
| P2-8 | Stream exhaustion DoS | Resource exhaustion | Configure stream limits |
-
Deploy HTTP-to-QUIC Gateway
- Simple Node.js/Go service
- Bridges HTTP/1.1 (port 8000) to QUIC (port 9334)
- Basic TLS termination
- Minimal transformation
-
Update API Client Configuration
- Change default URL to gateway address
- Update documentation
- Add connection validation
-
Add Connection Testing
async testConnection(): Promise<boolean> { try { await this.getProtocolInfo(); return true; } catch { return false; } }
-
Implement Critical Security Fixes
- P1-1: Move tokens to httpOnly cookies
- P1-2: Use Credential Management API
- P2-1: Add input validation with Zod
- P2-2: Generic error messages
-
Gateway Hardening
- Rate limiting
- Request validation
- DDoS protection
- TLS certificate management
-
Security Headers
'Content-Security-Policy': "default-src 'self'", 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'Strict-Transport-Security': 'max-age=31536000'
-
Implement Native Bridges
- iOS: Network.framework QUIC client
- Android: Cronet integration
- JavaScript bridge
-
Security Validation
- Certificate pinning
- Connection ID validation
- PQC handshake verification
-
Testing
- Connection stability
- Performance benchmarks
- Security audit
-
Performance
- Connection pooling
- 0-RTT resumption
- Request pipelining
-
Monitoring
- Connection metrics
- Error tracking
- Security event logging
- Connection establishment works (HTTP → Gateway → QUIC)
- TLS certificate validation
- Authentication flow (signup/login)
- Token storage security
- Rate limiting enforcement
- Error handling (no information leakage)
- Input validation on all endpoints
- CSRF protection (if browser-based)
- QUIC connection establishment
- Protocol detection accuracy
- HTTP-over-QUIC compatibility
- Connection migration behavior
- Amplification attack resistance
- Stream limit enforcement
- Idle timeout handling
- Connection ID randomization
-
Protocol Confusion
- Send ambiguous payloads:
ZHTP\x01GET / HTTP/1.1 - Try HTTP request smuggling
- Test protocol downgrade
- Send ambiguous payloads:
-
Connection Attacks
- Connection hijacking via IP spoofing
- Connection migration abuse
- Connection ID collision
-
Resource Exhaustion
- Open thousands of streams per connection
- Send partial requests
- Amplification attack simulation
-
Cryptographic Attacks
- PQC handshake manipulation
- TLS downgrade attempts
- Certificate validation bypass
| OWASP Issue | Status | Notes |
|---|---|---|
| A01: Broken Access Control | Session management needs review | |
| A02: Cryptographic Failures | Tokens in localStorage | |
| A03: Injection | ❌ Vulnerable | No input validation |
| A04: Insecure Design | Architecture mismatch | |
| A05: Security Misconfiguration | ❌ Vulnerable | Wrong default URL/port |
| A06: Vulnerable Components | ✅ Good | Dependencies up to date |
| A07: Authentication Failures | Credentials in request body | |
| A08: Software/Data Integrity | ✅ Good | TypeScript type safety |
| A09: Logging Failures | Client-side logging limited | |
| A10: SSRF | QUIC architecture limits risk |
Backend Support:
- ✅ Kyber512 (key encapsulation)
- ✅ Dilithium2 (digital signatures)
- ✅ ChaCha20 (symmetric encryption)
Client Support:
- ❌ JavaScript has no PQC libraries for QUIC
⚠️ Relies on gateway TLS termination⚠️ Native clients can use PQC
Recommendation: Document PQC benefits for native clients, limitations for browser clients.
Current documentation is misleading:
# INCORRECT STATEMENT (line 159):
- **HTTP Fallback**: 9333/TCP (if QUIC unavailable)
# CORRECT STATEMENT:
There is NO HTTP fallback. QUIC is mandatory.
For browser compatibility, deploy an HTTP-to-QUIC gateway.Create docs/ADR-001-QUIC-Only-Architecture.md:
# ADR-001: QUIC-Only Network Architecture
## Status: Accepted
## Context
ZHTP backend uses QUIC (UDP port 9334) as the ONLY transport protocol.
No TCP HTTP server exists.
## Decision
1. Browser clients MUST use HTTP-to-QUIC gateway
2. React Native clients SHOULD use native QUIC bridges
3. Default configuration points to gateway (port 8000), not backend (port 9334)
## Consequences
+ Better performance (QUIC benefits)
+ Post-quantum cryptography for native clients
- Gateway required for browser compatibility
- More complex deployment architectureAdd prominent warning:
## ⚠️ IMPORTANT: Architecture Requirements
This library requires either:
1. **HTTP-to-QUIC Gateway** (for browsers)
- Deploy gateway service on port 8000 (TCP)
- Gateway bridges to ZHTP backend on port 9334 (UDP/QUIC)
2. **Native QUIC Client** (for React Native)
- Implement platform-specific QUIC bridge
- See QUIC-TRANSPORT.md for details
**The library CANNOT connect directly to the ZHTP backend from browsers.**
Standard JavaScript fetch() uses HTTP/TCP, but the backend is QUIC/UDP only.- ✅ Deploy HTTP-to-QUIC Gateway - Blocking issue, nothing works without it
- ✅ Update Default Configuration - Change URL to gateway address
- ✅ Add Connection Validation - Fail fast with clear error messages
- ✅ Fix Token Storage - Move to httpOnly cookies
- ✅ Add Input Validation - Prevent injection attacks
- ✅ Implement Rate Limiting - Prevent brute force
- ✅ Generic Error Messages - Prevent information disclosure
- ✅ CSRF Protection - If browser-based
- ✅ Security Headers - Defense in depth
- ✅ Documentation Updates - Clarify architecture
- ✅ Native QUIC Clients - Better performance for React Native
- ✅ Connection Monitoring - Operational visibility
- ✅ Security Logging - Incident response
- ✅ Penetration Testing - Validate security
- ✅ WebTransport Support - Future browser compatibility
- ✅ Request Signing - Additional authentication layer
- ✅ Certificate Pinning - MITM prevention
- ✅ Connection Pooling - Performance optimization
- ✅ Metrics Collection - Analytics
- ✅ A/B Testing Framework - Feature rollout
The Sovereign Network API Client has a fundamental architecture incompatibility with the QUIC-only ZHTP backend. The library cannot function without either:
- HTTP-to-QUIC Gateway (required for browsers)
- Native QUIC Client (required for React Native)
The good news is that the QUIC backend has strong security properties:
- Mandatory TLS 1.3 encryption
- Post-quantum cryptography (PQC)
- Built-in rate limiting
- Protocol detection with validation
The bad news is that the API client library has critical security gaps:
- Session tokens in localStorage (XSS risk)
- Credentials in request body (logging/XSS risk)
- No input validation (injection risk)
- Wrong default configuration (connection failure)
The original security assessment was based on incorrect assumptions about HTTP/TCP architecture. This revised assessment reflects the actual QUIC/UDP architecture and identifies new QUIC-specific security concerns.
Browser
↓ fetch('http://localhost:8000/api/v1/identity')
Gateway (port 8000/TCP)
↓ HTTP/3 over QUIC
ZHTP Backend (port 9334/UDP)
↓ QuicHandler.accept_loop()
↓ Protocol detection (HTTP method detected)
↓ HttpCompatibilityLayer
↓ ZhtpRouter
↓ API Handlers
React Native App
↓ QuicClient.request()
Native Bridge (Swift/Kotlin)
↓ Network.framework / Cronet
↓ QUIC connection to port 9334/UDP
ZHTP Backend
↓ QuicHandler.accept_loop()
↓ Protocol detection (HTTP method detected)
↓ HttpCompatibilityLayer
↓ ZhtpRouter
↓ API Handlers
/Users/supertramp/Dev/The-Sovereign-Network/zhtp/src/unified_server.rs- Main server orchestration/Users/supertramp/Dev/The-Sovereign-Network/zhtp/src/server/quic_handler.rs- QUIC protocol handler/Users/supertramp/Dev/The-Sovereign-Network/zhtp/src/server/zhtp/compatibility.rs- HTTP compatibility layer/Users/supertramp/Dev/The-Sovereign-Network/lib-network/src/protocols/quic_mesh.rs- QUIC mesh protocol
/Users/supertramp/Dev/sovereign-network-api-client/src/core/zhtp-api-core.ts- Request handler/Users/supertramp/Dev/sovereign-network-api-client/src/vanilla-js/config-provider.ts- Configuration/Users/supertramp/Dev/sovereign-network-api-client/QUIC-TRANSPORT.md- QUIC documentation
Assessment Complete Next Steps: Deploy HTTP-to-QUIC gateway and address P0/P1 issues before any production use.