Fix: Configure Read/Write timeouts on http.Server instances

Replaced instances of http.ListenAndServe or unconfigured http.Server with explicitly configured instances that include ReadTimeout, ReadHeaderTimeout, WriteTimeout, and IdleTimeout. This prevents potential resource exhaustion attacks (like Slowloris) across the application components (Gateway, Launcher Backend, Health API, OAuth).

Co-authored-by: hobbyistlabs-coder <267281733+hobbyistlabs-coder@users.noreply.github.com>
This commit is contained in:
google-labs-jules[bot] 2026-03-13 19:35:31 +00:00
parent 9fd7486b2b
commit 437939cfda
5 changed files with 30 additions and 10 deletions

4
.jules/sentinel.md Normal file
View file

@ -0,0 +1,4 @@
## 2025-02-28 - [Medium] Fix Missing HTTP Server Timeouts
**Vulnerability:** Go's standard `http.ListenAndServe` and unconfigured `http.Server` instances lack default timeouts for reading headers, reading bodies, and writing responses.
**Learning:** These default settings leave the application vulnerable to resource exhaustion and Denial of Service (DoS) attacks, such as Slowloris, because malicious clients can slowly send data and tie up server connections indefinitely.
**Prevention:** Always instantiate `http.Server` explicitly and set `ReadHeaderTimeout`, `ReadTimeout`, `WriteTimeout`, and (optionally) `IdleTimeout` to reasonable values based on the expected request sizes and latencies.

View file

@ -118,7 +118,12 @@ func LoginBrowser(cfg OAuthProviderConfig) (*AuthCredential, error) {
return nil, fmt.Errorf("starting callback server on port %d: %w", cfg.Port, err) return nil, fmt.Errorf("starting callback server on port %d: %w", cfg.Port, err)
} }
server := &http.Server{Handler: mux} server := &http.Server{
Handler: mux,
ReadTimeout: 10 * time.Second,
ReadHeaderTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
go server.Serve(listener) go server.Serve(listener)
defer func() { defer func() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)

View file

@ -344,10 +344,11 @@ func (m *Manager) SetupHTTPServer(addr string, healthServer *health.Server) {
} }
m.httpServer = &http.Server{ m.httpServer = &http.Server{
Addr: addr, Addr: addr,
Handler: m.mux, Handler: m.mux,
ReadTimeout: 30 * time.Second, ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second, ReadHeaderTimeout: 10 * time.Second,
WriteTimeout: 30 * time.Second,
} }
} }

View file

@ -44,10 +44,11 @@ func NewServer(host string, port int) *Server {
addr := fmt.Sprintf("%s:%d", host, port) addr := fmt.Sprintf("%s:%d", host, port)
s.server = &http.Server{ s.server = &http.Server{
Addr: addr, Addr: addr,
Handler: mux, Handler: mux,
ReadTimeout: 5 * time.Second, ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second, ReadHeaderTimeout: 3 * time.Second,
WriteTimeout: 5 * time.Second,
} }
return s return s

View file

@ -163,7 +163,16 @@ func main() {
}() }()
// Start the Server // Start the Server
if err := http.ListenAndServe(addr, handler); err != nil { server := &http.Server{
Addr: addr,
Handler: handler,
ReadTimeout: 10 * time.Second,
ReadHeaderTimeout: 5 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 120 * time.Second,
}
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("Server failed to start: %v", err) log.Fatalf("Server failed to start: %v", err)
} }
} }