Slowloris Attack

ID

go.slowloris_attack

Severity

critical

Resource

Resource Management

Language

Go

Tags

CWE:400, NIST.SP.800-53, OWASP:2021:A4, PCI-DSS:6.5.6

Description

A Slowloris attack is a type of denial-of-service attack where an attacker sends partial HTTP requests to keep server connections open, exhausting resources and preventing legitimate users from accessing the server.

Rationale

In a Slowloris attack, the attacker exploits the server’s ability to handle multiple connections by sending incomplete requests at a very slow rate.

This keeps the connections open and consumes server resources, effectively denying access to legitimate users.

Go web servers can be vulnerable if they do not manage connection timeouts and request limits properly.

Example of a vulnerable server setup:

package slowloris_attack

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
	})

	server := &http.Server{ // FLAW
		Addr: ":9875",
	}

	err := server.ListenAndServe()
	if err != nil {
		panic(err)
	}
}

In this example, the server lacks timeout configurations, making it susceptible to Slowloris attacks by handling numerous open connections indefinitely.

Remediation

  1. Set Timeouts: Configure server timeouts to limit how long a connection can remain open without completing. Set read and write timeouts to prevent resources from being exhausted.

  2. Connection Limits: Use reverse proxies or load balancers to limit the number of simultaneous connections and manage traffic efficiently.

  3. Use a Web Application Firewall (WAF): Implement a WAF to detect and mitigate Slowloris attack patterns.

  4. Monitor and Alert: Continuously monitor server metrics for unusual patterns, such as a high number of open or idle connections, and set up alerts for potential attack detection.

By following these strategies, you can significantly reduce the risk of Slowloris attacks against Go-based applications.

The remediation example would look like this:

package main

import (
    "net/http"
    "time"
)

func main() {
    server := &http.Server{
        Addr:         ":8080",
        Handler:      http.DefaultServeMux,
        ReadHeaderTimeout:  3 * time.Second,
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, world!"))
    })

    server.ListenAndServe()
}

References

  • CWE-400 : Uncontrolled Resource Consumption.