Say the source host is signed as the URL writes it (part of #246)
check / check (push) Waiting to run

The Signature Specification read as though the hostname were signed
with ":" and the port appended. The code signs the host segment as the
URL writes it up to the first "/", lower-cased, so IPv6 brackets and a
":" with or without a port are kept. The README line, the TODO.md entry
and the parser comment now say so.

Model: opus-5-5
This commit is contained in:
2026-10-15 10:03:47 +00:00
parent 589318db97
commit 6453b9a125
3 changed files with 7 additions and 5 deletions
+3 -2
View File
@@ -418,8 +418,9 @@ HMAC-SHA256(secret, "host:path:query:width:height:format:expiration:quality:fit"
Where:
- `host` — source origin hostname in lower case, whatever its case in the URL,
followed by `:` and the port when the URL has one (e.g. `cdn.example.com`)
- `host` — source host as the URL writes it up to the first `/`, in lower case,
keeping an IPv6 address's brackets and any `:` and port after it (e.g.
`cdn.example.com`, `cdn.example.com:8443`, `[2001:db8::1]:8443`)
- `path` — source path (e.g. `/photos/cat.jpg`), with each `%` written as `%25`
and each `:` as `%3A`, so `/photos/a:b.jpg` is signed as `/photos/a%3Ab.jpg`
- `query` — source query string, empty string if none, with `%` and `:` written
+2 -2
View File
@@ -39,8 +39,8 @@ P2: security: per-origin rate limiting
password, with 400. A host with a port, or with a `:` and no port, needs a
signature even when it is allowlisted. That is checked in the image service,
not in `allowlist.IsAllowed`, which also matches `referer_blocklist`, where a
`Referer` is blocked whatever its port. A URL is signed over the lower-cased
host.
`Referer` is blocked whatever its port. A URL is signed over its host as it
writes it, in lower case, with any IPv6 brackets, `:` and port kept.
- 2026-10-15 a `:` in the source path or query no longer moves where the path
ends and the query begins (closes #247): the signed data and the cache key
joined host, path and query with `:` and no escaping, so a URL signed for
+2 -1
View File
@@ -151,7 +151,8 @@ func parseImageComponents(remainder string) (*ParsedURL, error) {
}
// Host names do not depend on letter case, so the allowlist, the upstream
// connection limits and the cache see one spelling of each host
// connection limits, the cache and the signature see one spelling of each
// host
host = strings.ToLower(host)
// Extract query string if present in path