server: limit request body size on POST endpoints

Add io.LimitReader (1 MB cap) to /collect, /evaluate, and /report
handlers to prevent memory exhaustion from oversized requests.
This commit is contained in:
nemunaire 2026-04-10 16:20:48 +07:00
commit ec4efcf671

View file

@ -18,12 +18,16 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"log" "log"
"net/http" "net/http"
"strings" "strings"
"time" "time"
) )
// maxRequestBodySize is the maximum allowed size for incoming request bodies (1 MB).
const maxRequestBodySize = 1 << 20
// Server is a generic HTTP server for external checkers. // Server is a generic HTTP server for external checkers.
// It always exposes /health and /collect. If the provider implements // It always exposes /health and /collect. If the provider implements
// CheckerDefinitionProvider, it also exposes /definition and /evaluate. // CheckerDefinitionProvider, it also exposes /definition and /evaluate.
@ -101,7 +105,7 @@ func (s *Server) handleDefinition(w http.ResponseWriter, r *http.Request) {
func (s *Server) handleCollect(w http.ResponseWriter, r *http.Request) { func (s *Server) handleCollect(w http.ResponseWriter, r *http.Request) {
var req ExternalCollectRequest var req ExternalCollectRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { if err := json.NewDecoder(io.LimitReader(r.Body, maxRequestBodySize)).Decode(&req); err != nil {
writeJSON(w, http.StatusBadRequest, ExternalCollectResponse{ writeJSON(w, http.StatusBadRequest, ExternalCollectResponse{
Error: fmt.Sprintf("invalid request body: %v", err), Error: fmt.Sprintf("invalid request body: %v", err),
}) })
@ -131,7 +135,7 @@ func (s *Server) handleCollect(w http.ResponseWriter, r *http.Request) {
func (s *Server) handleEvaluate(w http.ResponseWriter, r *http.Request) { func (s *Server) handleEvaluate(w http.ResponseWriter, r *http.Request) {
var req ExternalEvaluateRequest var req ExternalEvaluateRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { if err := json.NewDecoder(io.LimitReader(r.Body, maxRequestBodySize)).Decode(&req); err != nil {
writeJSON(w, http.StatusBadRequest, ExternalEvaluateResponse{ writeJSON(w, http.StatusBadRequest, ExternalEvaluateResponse{
Error: fmt.Sprintf("invalid request body: %v", err), Error: fmt.Sprintf("invalid request body: %v", err),
}) })
@ -159,7 +163,7 @@ func (s *Server) handleEvaluate(w http.ResponseWriter, r *http.Request) {
func (s *Server) handleReport(w http.ResponseWriter, r *http.Request) { func (s *Server) handleReport(w http.ResponseWriter, r *http.Request) {
var req ExternalReportRequest var req ExternalReportRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { if err := json.NewDecoder(io.LimitReader(r.Body, maxRequestBodySize)).Decode(&req); err != nil {
writeJSON(w, http.StatusBadRequest, map[string]string{ writeJSON(w, http.StatusBadRequest, map[string]string{
"error": fmt.Sprintf("invalid request body: %v", err), "error": fmt.Sprintf("invalid request body: %v", err),
}) })