From e2ac30287bf39ae67f19f939d27455feb530b5d0 Mon Sep 17 00:00:00 2001 From: clawbot Date: Sun, 1 Mar 2026 16:35:38 -0800 Subject: [PATCH] fix: restrict webhook endpoint to POST only (closes #20) Add method check at the top of HandleWebhook, returning 405 Method Not Allowed with an Allow: POST header for any non-POST request. This prevents GET, PUT, DELETE, etc. from being accepted at entrypoint URLs. --- internal/handlers/webhook.go | 7 +++++++ internal/server/routes.go | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/handlers/webhook.go b/internal/handlers/webhook.go index 0912454..fbc1e26 100644 --- a/internal/handlers/webhook.go +++ b/internal/handlers/webhook.go @@ -15,8 +15,15 @@ const ( ) // HandleWebhook handles incoming webhook requests at entrypoint URLs. +// Only POST requests are accepted; all other methods return 405 Method Not Allowed. func (h *Handlers) HandleWebhook() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + w.Header().Set("Allow", "POST") + http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) + return + } + entrypointUUID := chi.URLParam(r, "uuid") if entrypointUUID == "" { http.NotFound(w, r) diff --git a/internal/server/routes.go b/internal/server/routes.go index 457b570..d0c1773 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -109,6 +109,8 @@ func (s *Server) SetupRoutes() { r.Post("/targets", s.h.HandleTargetCreate()) // Add target }) - // Entrypoint endpoint - accepts incoming webhook POST requests + // Entrypoint endpoint — accepts incoming webhook POST requests only. + // Using HandleFunc so the handler itself can return 405 for non-POST + // methods (chi's Method routing returns 405 without Allow header). s.router.HandleFunc("/webhook/{uuid}", s.h.HandleWebhook()) }