Correct a typo, also enforce host being a required header #3

Merged
floatingghost merged 3 commits from typo into main 2026-05-04 18:57:12 +00:00
2 changed files with 17 additions and 4 deletions
Showing only changes of commit f201fe1237 - Show all commits

enforce the existence of the host header on signatures

FloatingGhost 2026-04-30 17:56:28 +01:00

View file

@ -258,6 +258,9 @@ defmodule HTTPSignatures do
defp check_required(used_headers, header_defs, has_body) do
with true <- !has_body || uses_header?("digest", used_headers, header_defs),
true <-
uses_header?("host", used_headers, header_defs) ||
uses_header?(:host, used_headers, header_defs),
true <- @request_target in used_headers,
true <-
uses_header?("date", used_headers, header_defs) ||

View file

@ -49,6 +49,10 @@ defmodule HttpSignaturesTest do
keyId="Test",algorithm="rsa-sha256",headers="(request-target) host date content-type digest content-length",signature="Ef7MlxLXoBovhil3AlyjtBwAL9g4TN3tibLj7uuNB3CROat/9KaeQ4hW2NiJ+pZ6HQEOx9vYZAyi+7cmIkmJszJCut5kQLAwuX+Ms/mUFvpKlSo9StS2bMXDBNjOh4Auj774GFj4gwjS+3NhFeoqyr/MuN6HsEnkvn6zdgfE2i0="
"""
@hostless_signature """
keyId="Test",algorithm="rsa-sha256",headers="(request-target) date content-type digest content-length",signature="Ef7MlxLXoBovhil3AlyjtBwAL9g4TN3tibLj7uuNB3CROat/9KaeQ4hW2NiJ+pZ6HQEOx9vYZAyi+7cmIkmJszJCut5kQLAwuX+Ms/mUFvpKlSo9StS2bMXDBNjOh4Auj774GFj4gwjS+3NhFeoqyr/MuN6HsEnkvn6zdgfE2i0="
"""
defp signed_conn(signature, headers, body_params \\ @stub_body),
do: %{
req_headers: [{"signature", signature} | headers],
@ -88,6 +92,10 @@ defmodule HttpSignaturesTest do
)
end
test "rejects a signature without a host header" do
assert {:error, :missing_required_header} == check_signature(@hostless_signature)
end
test "it validates a conn" do
conn =
signed_conn(
@ -358,10 +366,11 @@ defmodule HttpSignaturesTest do
test "rejects too old signatures" do
conn =
signed_conn(
"keyId=\"Test\",algorithm=\"rsa-sha256\",headers=\"(request-target) date digest\",signature=\"fTmDCQYXsib05+Np0R3jQhG5KYu8v8chjiZnpZxKMnTPLJ6C/XDeqTIAvBtikuIrSWNG0k3/xSMXR3c1IVw/T5lwo9KAjsZU39ztYGBckE8X9BdT1GklpyWDtI4X9MvBrq5lmMn/r1gbQFzelQEF1+RdK6kbDwg8goAYGEkm9KE=\"",
"keyId=\"Test\",algorithm=\"rsa-sha256\",headers=\"(request-target) date host digest\",signature=\"fTmDCQYXsib05+Np0R3jQhG5KYu8v8chjiZnpZxKMnTPLJ6C/XDeqTIAvBtikuIrSWNG0k3/xSMXR3c1IVw/T5lwo9KAjsZU39ztYGBckE8X9BdT1GklpyWDtI4X9MvBrq5lmMn/r1gbQFzelQEF1+RdK6kbDwg8goAYGEkm9KE=\"",
[
{"date", "Wed, 09 Feb 2000 00:00:00 GMT"},
{"digest", "SHA256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}
{"digest", "SHA256-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
{"host", "example.com"}
]
)
@ -372,10 +381,11 @@ defmodule HttpSignaturesTest do
test "returns an error on unknown key" do
conn =
signed_conn(
"keyId=\"unknown_id\",algorithm=\"rsa-sha256\",headers=\"(request-target) date digest\",signature=\"CTYdK5a6lYMxzmqjLOpvRRASoxo2Rqib2VrAvbR5HaTn80kiImj15pCpAyx8IZp53s0Fn/y8MjCTzp+absw8kxx0k2sQAXYs2iy6xhdDUe7iGzz+XLAEqLyZIZfecynaU2nb3Z2XnFDjhGjR1vj/JP7wiXpwp6o1dpDZj+KT2vxHtXuB9585V+sOHLwSB1cGDbAgTy0jx/2az2EGIKK2zkw1KJuAZm0DDMSZalp/30P8dl3qz7DV2EHdDNfaVtrs5BfbDOZ7t1hCcASllzAzgVGFl0BsrkzBfRMeUMRucr111ZG+c0BNOEtJYOHSyZsSSdNknElggCJekONYMYk5ZA==\"",
"keyId=\"unknown_id\",algorithm=\"rsa-sha256\",headers=\"(request-target) date host digest\",signature=\"CTYdK5a6lYMxzmqjLOpvRRASoxo2Rqib2VrAvbR5HaTn80kiImj15pCpAyx8IZp53s0Fn/y8MjCTzp+absw8kxx0k2sQAXYs2iy6xhdDUe7iGzz+XLAEqLyZIZfecynaU2nb3Z2XnFDjhGjR1vj/JP7wiXpwp6o1dpDZj+KT2vxHtXuB9585V+sOHLwSB1cGDbAgTy0jx/2az2EGIKK2zkw1KJuAZm0DDMSZalp/30P8dl3qz7DV2EHdDNfaVtrs5BfbDOZ7t1hCcASllzAzgVGFl0BsrkzBfRMeUMRucr111ZG+c0BNOEtJYOHSyZsSSdNknElggCJekONYMYk5ZA==\"",
[
{"date", "Sun, 11 Mar 2018 12:19:36 GMT"},
{"digest", "SHA-256=V7Hl6qDK2m8WzNsjzNYSBISi9VoIXLFlyjF/a5o1SOc="}
{"digest", "SHA-256=V7Hl6qDK2m8WzNsjzNYSBISi9VoIXLFlyjF/a5o1SOc="},
{"host", "example.com"}

nit: this and the previous test already fail before it becomes relevant anyway, but due to adding host to headers this header is not just missing the key (or for the test above "too old"), but also plain cryptographically incorrect (the current value did not actually sign the hostheader content)

nit: this and the previous test already fail before it becomes relevant anyway, but due to adding `host` to `headers` this header is not just missing the key (or for the test above "too old"), but also plain cryptographically incorrect (the current value did not actually sign the `host`header content)
]
)