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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions