security: add request body size limit to prevent DoS
Add MaxRequestSize configuration to HTTPConfig with a default of 1MB. Use http.MaxBytesReader to enforce the limit, returning 413 Request Entity Too Large when exceeded. This prevents memory exhaustion attacks where an attacker sends arbitrarily large request bodies. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -481,6 +481,59 @@ func TestHTTPTransportOptionsRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPTransportRequestBodyTooLarge(t *testing.T) {
|
||||
_, ts := testHTTPTransport(t, HTTPConfig{
|
||||
MaxRequestSize: 100, // Very small limit for testing
|
||||
})
|
||||
|
||||
// Create a request body larger than the limit
|
||||
largeBody := make([]byte, 200)
|
||||
for i := range largeBody {
|
||||
largeBody[i] = 'x'
|
||||
}
|
||||
|
||||
req, _ := http.NewRequest("POST", ts.URL+"/mcp", bytes.NewReader(largeBody))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatalf("Request failed: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusRequestEntityTooLarge {
|
||||
t.Errorf("Expected 413 for oversized request, got %d", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPTransportRequestBodyWithinLimit(t *testing.T) {
|
||||
_, ts := testHTTPTransport(t, HTTPConfig{
|
||||
MaxRequestSize: 10000, // Reasonable limit
|
||||
})
|
||||
|
||||
// Send initialize request (should be well within limit)
|
||||
initReq := Request{
|
||||
JSONRPC: "2.0",
|
||||
ID: 1,
|
||||
Method: MethodInitialize,
|
||||
Params: json.RawMessage(`{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}`),
|
||||
}
|
||||
body, _ := json.Marshal(initReq)
|
||||
|
||||
req, _ := http.NewRequest("POST", ts.URL+"/mcp", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatalf("Request failed: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("Expected 200 for valid request within limit, got %d", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsLocalhostOrigin(t *testing.T) {
|
||||
tests := []struct {
|
||||
origin string
|
||||
|
||||
Reference in New Issue
Block a user