From 94ab6e7bf7293e987ae98b4daa51ea131c2671ba Mon Sep 17 00:00:00 2001 From: vshakitskiy Date: Sat, 14 Mar 2026 18:59:14 +0000 Subject: [PATCH] introduce allowlist for trailer headers --- CHANGELOG.md | 2 +- dev/benchmark.gleam | 2 ++ src/ewe/internal/http1.gleam | 20 +++++--------------- 3 file(s) changed, 8 insertion(s)(+), 16 deletion(s)(-) diff --git a/CHANGELOG.md b/CHANGELOG.md --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ # Unreleased - Remove all usage of `string.inspect` as it's a huge anti-pattern for logging. -- Patch infinite loop on rejected trailer headers inside `handle_trailers`. +- Patch infinite loops and adjust allowed entries for trailer headers. # v3.0.4 - 13.03.2026 diff --git a/dev/benchmark.gleam b/dev/benchmark.gleam --- a/dev/benchmark.gleam +++ b/dev/benchmark.gleam @@ -24,6 +24,8 @@ http.Post, ["user"] -> { case ewe.read_body(req, 40_000_000) { Ok(req) -> { + echo req.headers + let content_type = req |> request.get_header("content-type") diff --git a/src/ewe/internal/http1.gleam b/src/ewe/internal/http1.gleam --- a/src/ewe/internal/http1.gleam +++ b/src/ewe/internal/http1.gleam @@ -508,9 +508,7 @@ case field_name { Ok(field_name) -> { - case - set.contains(set, field_name) && !is_forbidden_trailer(field_name) - { + case set.contains(set, field_name) && is_allowed_trailer(field_name) { True -> { case bit_array.to_string(value) { Ok(value) -> { @@ -530,18 +528,10 @@ } } -/// Checks if a header field is forbidden in trailers. -fn is_forbidden_trailer(field: String) -> Bool { - case string.lowercase(field) { - "transfer-encoding" - | "content-length" - | "host" - | "cache-control" - | "expect" - | "max-forwards" - | "pragma" - | "range" - | "te" -> True +/// Checks if a trailer field is allowed. +fn is_allowed_trailer(field: String) -> Bool { + case field { + "server-timing" | "content-digest" | "repr-digest" -> True _ -> False } } -- tangled.sh