Go 1.27.2 and 1.26.9 patch net/http: update your Sume webhook receiver
Go 1.27.2 and 1.26.9 (2026-10-08) list security fixes in net/http and crypto/tls. A stdlib receiver for Sume webhooks that verifies the signature, in two files.

If a Go service receives Sume webhooks, rebuild it on Go 1.27.2 (or 1.26.9 if you stay on the 1.26 line). Both were released on 2026-10-08, and the Go release history lists security fixes to net/http, crypto/tls, net/textproto, html/template, and os in each. A public webhook endpoint is a net/http server on the open internet, so it is a service that should take the patch first.
What the release history says
The Go release history (read 2026-10-10) gives only package names for the security fixes and points to the milestone on the Go issue tracker for detail. I did not follow that to individual advisories, so this post makes no claim about what the bugs are or whether a webhook receiver is exposed to them.
| Release | Date | Security fixes listed in | Also in the entry |
|---|---|---|---|
| go1.27.2 | 2026-10-08 | go command, crypto/tls, html/template, net/http, net/textproto, os | Bug fixes to net/http, os, encoding/json, encoding/json/v2, crypto/mlkem |
| go1.26.9 | 2026-10-08 | go command, crypto/tls, html/template, net/http, net/textproto, os | Bug fixes to net/http, os, crypto/mlkem |
| go1.27.1 | 2026-09-01 | None listed for these packages | Bug fixes to net/http, os, encoding/json |
A receiver that checks the signature
The webhooks page says Sume signs <timestamp>.<raw_body> with HMAC SHA-256 and sends x-sume-webhook-timestamp and x-sume-webhook-signature: sume-v1=<hex>. During a secret rotation the signature header holds one sume-v1= entry per live secret, comma separated, and a delivery is valid if any entry matches. The first file is the verifier.
It rejects an empty secret, a timestamp older than five minutes in either direction, and any entry that does not match, and it compares every entry so timing does not reveal which one matched.
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"strconv"
"strings"
"time"
)
func verify(secret string, raw []byte, ts, header string) bool {
n, err := strconv.ParseInt(ts, 10, 64)
if err != nil || secret == "" || time.Since(time.Unix(n, 0)).Abs() > 5*time.Minute {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(ts + "."))
mac.Write(raw)
want := []byte("sume-v1=" + hex.EncodeToString(mac.Sum(nil)))
ok := false
for _, e := range strings.Split(header, ",") {
if hmac.Equal([]byte(strings.TrimSpace(e)), want) {
ok = true // keep looping: rotation sends one entry per live secret
}
}
return ok
}The second file is the handler. It reads the raw body with a 1 MiB cap before it checks anything, verifies, and answers 204. Replace the comment with a durable write keyed by job_id, because the docs treat job_id as the idempotency key and say Sume retries up to 10 times.
package main
import (
"io"
"log"
"net/http"
"os"
)
func main() {
secret := os.Getenv("SUME_COM_WEBHOOK_SIGNING_SECRET")
http.HandleFunc("/sume/webhook", func(w http.ResponseWriter, r *http.Request) {
raw, err := io.ReadAll(http.MaxBytesReader(w, r.Body, 1<<20))
ts, sig := r.Header.Get("x-sume-webhook-timestamp"), r.Header.Get("x-sume-webhook-signature")
if err != nil || !verify(secret, raw, ts, sig) {
http.Error(w, "bad signature", http.StatusUnauthorized)
return
}
w.WriteHeader(http.StatusNoContent) // store job_id durably first, then 2xx
})
log.Fatal(http.ListenAndServe(":8080", nil))
}Run and pin it
I vetted both files and ran them on Go 1.27.1 with a signed test request. A request carrying sume-v1=bad,sume-v1=<good> returned 204, and one with only a bad entry returned 401. Set go 1.27.2 in go.mod, or run go get go@1.27.2 if your module should not build with anything older, then rebuild and redeploy the container.
- The receiver has one job: verify, store, answer. Do the work that calls other services after you answer.
- Sume allows each attempt 10 seconds, so a handler that does slow work counts against the retry budget.
- Keep polling
GET /v1/jobs/:id/statusas a backup for events that never arrive. - Rebuild every Go binary that talks to Sume, not only the receiver. The client side also links
net/httpandcrypto/tls.
Sources
Related posts
More in Developers
- Go errgroup SetLimit: submit Sume jobs within your concurrency budget
Cap in-flight Sume submissions in Go with errgroup.SetLimit, size the width from your concurrency limit, and keep one Idempotency-Key per item. 30 lines.
- Grok Image on Sume: one image per call, so fan out four in Python
x-ai/grok-image lists n as 1 to 1 in the Sume catalog. How to get four variants with four parallel calls, what it costs, and how to stay under queue limits.
- Grok Imagine ignores aspect_ratio on image-to-video; Sume rejects it
xAI says image-to-video output matches the input image and ignores aspect_ratio. Sume's Grok row goes further and rejects the field. Crop the still first.
- Grok Imagine Lite's 10 requests per second vs Sume plan concurrency
xAI lists a 10 requests per second limit and Batch API for Grok Imagine 1.5 Lite. On Sume, a clip batch is bounded by plan concurrency and queue capacity.
Written by Sume