Skip to content

🚨 CRITICAL: DoS Vulnerabilities - Memory Exhaustion and Resource Limits #1

@amitu

Description

@amitu

Summary

The fastn-p2p implementation contains multiple Denial of Service vulnerabilities that could allow attackers to crash servers or exhaust resources with minimal effort.

Severity: CRITICAL

Attack Vectors

1. Memory Exhaustion via Unbounded JSON Parsing

Location: fastn-net/src/utils_iroh.rs:153-177 (next_json() and next_string())

pub async fn next_json<T: serde::de::DeserializeOwned>(
    recv: &mut iroh::endpoint::RecvStream,
) -> eyre::Result<T> {
    let mut buffer = Vec::with_capacity(1024);
    loop {
        // No size limit - reads until newline!
        buffer.push(byte[0]);
    }
}

Attack: Send a 10GB JSON payload in a single line → instant OOM

2. Connection Pool Exhaustion

Location: fastn-net/src/get_stream.rs:9-16

  • No limit on connection pool size
  • Attackers can open thousands of connections
  • Each connection consumes memory and file descriptors

3. Unbounded Task Spawning

Location: fastn-p2p/src/server/builder.rs:198-202

crate::spawn(async move {
    if let Err(e) = handle_connection(conn, &request_handlers, &stream_handlers).await {
        tracing::error!("Connection error: {}", e);
    }
});

Attack: Rapidly open connections to spawn unlimited tasks

4. Idle Timeout Bypass

Location: fastn-net/src/get_stream.rs:244-248

  • Connections timeout after 60 seconds (5 * 12 second intervals)
  • Attackers can send minimal data every 12 seconds to keep connections alive forever

Proposed Fixes

Immediate (Stop the bleeding)

// 1. Add max buffer size
const MAX_JSON_SIZE: usize = 1024 * 1024; // 1MB
pub async fn next_json_limited<T>(recv: &mut RecvStream, max_size: usize) -> Result<T> {
    let mut buffer = Vec::with_capacity(1024);
    loop {
        if buffer.len() > max_size {
            return Err(eyre::anyhow!("Payload exceeds size limit"));
        }
        // ... rest
    }
}

// 2. Connection pool limits
const MAX_CONNECTIONS_PER_PEER: usize = 10;
const MAX_TOTAL_CONNECTIONS: usize = 1000;

// 3. Rate limiting
const MAX_CONNECTIONS_PER_SECOND: u32 = 10;

Architecture Changes Needed

  • Implement streaming JSON parser for large payloads
  • Add connection pool with eviction policy
  • Implement rate limiting at connection accept level
  • Add resource quotas per peer
  • Implement backpressure mechanisms

Impact

  • Without fix: Single attacker can crash any fastn-p2p server in seconds
  • Attack cost: Minimal (simple script, low bandwidth)
  • Defense priority: CRITICAL - fix before any production deployment

Testing

# PoC: Memory exhaustion
echo '{"data": "'$(python3 -c "print('A' * 1000000000)")'"}\n' | nc target 9999

# PoC: Connection exhaustion  
for i in {1..10000}; do
    nc target 9999 &
done

References

  • OWASP: Denial of Service Cheat Sheet
  • CWE-400: Uncontrolled Resource Consumption
  • CWE-770: Allocation Without Limits

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions