Skip to content

Security: Missing ReadHeaderTimeout enables Slowloris DoS attacks #36

@sgaunet

Description

@sgaunet

Description

The HTTP server configuration is missing ReadHeaderTimeout, making it vulnerable to Slowloris-style DoS attacks where attackers slowly send headers to exhaust connection limits.

Location

http-echo.go:260-267

server := &http.Server{
    Addr:           ":8080",
    Handler:        h,
    ReadTimeout:    readTimeout,
    WriteTimeout:   writeTimeout,
    IdleTimeout:    idleTimeout,
    MaxHeaderBytes: maxHeaderBytes,
    // ReadHeaderTimeout is missing
}

Impact

  • Severity: MEDIUM (Security)
  • Attack Vector: Slowloris attack (slow HTTP headers)
  • Connection exhaustion from attackers holding connections open
  • Legitimate users cannot connect
  • Service unavailability

Vulnerability Details

Without ReadHeaderTimeout, ReadTimeout only starts after headers are read. An attacker can:

  1. Open many connections
  2. Send headers one byte at a time very slowly
  3. Hold connections open indefinitely
  4. Exhaust server connection limits
# Slowloris attack example
slowhttptest -c 1000 -H -g -o slowloris.html -i 10 -r 200 -t GET -u http://target:8080/

Recommended Fix

Add ReadHeaderTimeout to the server configuration:

const (
    readHeaderTimeout = 5 * time.Second  // Add this constant
    readTimeout       = 10 * time.Second
    writeTimeout      = 10 * time.Second
    idleTimeout       = 60 * time.Second
    maxHeaderBytes    = 1 << 20
    shutdownTimeout   = 5 * time.Second
)

func main() {
    var h helloWorldhandler
    server := &http.Server{
        Addr:              ":8080",
        Handler:           h,
        ReadTimeout:       readTimeout,
        ReadHeaderTimeout: readHeaderTimeout, // Add this
        WriteTimeout:      writeTimeout,
        IdleTimeout:       idleTimeout,
        MaxHeaderBytes:    maxHeaderBytes,
    }
    // ...
}

Why This Matters

  • ReadHeaderTimeout: Limits time to read request headers (guards against slow header attacks)
  • ReadTimeout: Limits time to read headers + body (but only starts after headers complete)
  • WriteTimeout: Limits time to write response
  • IdleTimeout: Limits time between requests on keep-alive connections

Testing

  • Use slowhttptest to simulate Slowloris attacks before/after fix
  • Verify connections are closed after 5 seconds with slow header sends
  • Monitor connection count under attack
# Install slowhttptest
# macOS: brew install slowhttptest
# Linux: apt-get install slowhttptest

# Test before fix (should succeed in exhausting connections)
slowhttptest -c 1000 -H -g -o before.html -i 10 -r 200 -t GET -u http://localhost:8080/

# Test after fix (should fail to exhaust connections)
slowhttptest -c 1000 -H -g -o after.html -i 10 -r 200 -t GET -u http://localhost:8080/

Priority

High - Common attack vector that's trivial to fix.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions