fix: limit webhook request body size to 1MB to prevent DoS (closes #1)
This commit is contained in:
parent
d4eae284b5
commit
e212910143
@ -426,6 +426,47 @@ func addChiURLParams(
|
||||
)
|
||||
}
|
||||
|
||||
func TestHandleWebhookRejectsOversizedBody(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCtx := setupTestHandlers(t)
|
||||
|
||||
// Create an app first
|
||||
createdApp, createErr := testCtx.appSvc.CreateApp(
|
||||
context.Background(),
|
||||
app.CreateAppInput{
|
||||
Name: "oversize-test-app",
|
||||
RepoURL: "git@example.com:user/repo.git",
|
||||
Branch: "main",
|
||||
},
|
||||
)
|
||||
require.NoError(t, createErr)
|
||||
|
||||
// Create a body larger than 1MB - it should be silently truncated
|
||||
// and the webhook should still process (or fail gracefully on parse)
|
||||
largePayload := strings.Repeat("x", 2*1024*1024) // 2MB
|
||||
request := httptest.NewRequest(
|
||||
http.MethodPost,
|
||||
"/webhook/"+createdApp.WebhookSecret,
|
||||
strings.NewReader(largePayload),
|
||||
)
|
||||
request = addChiURLParams(
|
||||
request,
|
||||
map[string]string{"secret": createdApp.WebhookSecret},
|
||||
)
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
request.Header.Set("X-Gitea-Event", "push")
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
||||
handler := testCtx.handlers.HandleWebhook()
|
||||
handler.ServeHTTP(recorder, request)
|
||||
|
||||
// Should still return OK (payload is truncated and fails JSON parse,
|
||||
// but webhook service handles invalid JSON gracefully)
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
}
|
||||
|
||||
func TestHandleWebhookReturns404ForUnknownSecret(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@ -9,6 +9,9 @@ import (
|
||||
"git.eeqj.de/sneak/upaas/internal/models"
|
||||
)
|
||||
|
||||
// maxWebhookBodySize is the maximum allowed size of a webhook request body (1MB).
|
||||
const maxWebhookBodySize = 1 << 20
|
||||
|
||||
// HandleWebhook handles incoming Gitea webhooks.
|
||||
func (h *Handlers) HandleWebhook() http.HandlerFunc {
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
@ -38,8 +41,8 @@ func (h *Handlers) HandleWebhook() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
// Read request body
|
||||
body, readErr := io.ReadAll(request.Body)
|
||||
// Read request body with size limit to prevent memory exhaustion
|
||||
body, readErr := io.ReadAll(io.LimitReader(request.Body, maxWebhookBodySize))
|
||||
if readErr != nil {
|
||||
h.log.Error("failed to read webhook body", "error", readErr)
|
||||
http.Error(writer, "Bad Request", http.StatusBadRequest)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user