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
-
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.
-
Connection Limits: Use reverse proxies or load balancers to limit the number of simultaneous connections and manage traffic efficiently.
-
Use a Web Application Firewall (WAF): Implement a WAF to detect and mitigate Slowloris attack patterns.
-
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.