The signed data and the cache key joined host, path and query with : and no escaping, so path /a:b with no query and path /a with query b: gave the same string. A URL signed for https://h/a:b verified for https://h/a?b:, and the two shared a cached image.
Both now write each % in the path and the query as %25 and each : as %3A before joining them. The host never holds / and the path always starts with /, so the joined string can be read back one way only. A path and query holding neither character are signed and keyed as before, which is why the existing known-answer vectors in internal/signature/golden_test.go and the README example are unchanged. New vectors pin a path with :, a query with :, and a % in both; they were computed outside pixa with openssl dgst -hmac.
Signature Specification in README.md states the escaping. Anyone who signs URLs outside pixa has to apply it to path and query, or a URL whose path or query holds % or : is refused with 401.
Judgement call: as the plan says, internal/signature and internal/imgcache each have their own copy of the four-line escaping function, under the same name.
Judgement call: the new cache key test sits next to TestCacheKey in storage_internal_test.go; the new signature tests are in a new file, escaping_test.go. No existing test changed.
Model: opus-5-5
Fixes https://git.eeqj.de/sneak/pixa/issues/247.
The signed data and the cache key joined host, path and query with `:` and no escaping, so path `/a:b` with no query and path `/a` with query `b:` gave the same string. A URL signed for `https://h/a:b` verified for `https://h/a?b:`, and the two shared a cached image.
Both now write each `%` in the path and the query as `%25` and each `:` as `%3A` before joining them. The host never holds `/` and the path always starts with `/`, so the joined string can be read back one way only. A path and query holding neither character are signed and keyed as before, which is why the existing known-answer vectors in `internal/signature/golden_test.go` and the README example are unchanged. New vectors pin a path with `:`, a query with `:`, and a `%` in both; they were computed outside pixa with `openssl dgst -hmac`.
Signature Specification in `README.md` states the escaping. Anyone who signs URLs outside pixa has to apply it to path and query, or a URL whose path or query holds `%` or `:` is refused with 401.
- Judgement call: as the plan says, `internal/signature` and `internal/imgcache` each have their own copy of the four-line escaping function, under the same name.
- Judgement call: the new cache key test sits next to `TestCacheKey` in `storage_internal_test.go`; the new signature tests are in a new file, `escaping_test.go`. No existing test changed.
Model: opus-5-5
A URL signed for path /a:b with no query must not verify for path /a with
query b:, and the two must not share a cache key. New known-answer vectors
pin the signature of a path with ":", a query with ":", and a "%" in path
and query, with "%" written as "%25" and ":" as "%3A" in the signed data.
These fail until the fix for
#247 lands.
Model: opus-5-5
The signed data and the cache key joined host, path and query with ":"
and no escaping, so path /a:b with no query and path /a with query b:
gave the same string: a URL signed for one verified for the other, and
whichever was fetched first was served for both. Both now write each "%"
in the path and query as "%25" and each ":" as "%3A" before joining them.
A path and query holding neither are signed and keyed as before.
"Signature Specification" in README.md states the escaping.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #247.
The signed data and the cache key joined host, path and query with
:and no escaping, so path/a:bwith no query and path/awith queryb:gave the same string. A URL signed forhttps://h/a:bverified forhttps://h/a?b:, and the two shared a cached image.Both now write each
%in the path and the query as%25and each:as%3Abefore joining them. The host never holds/and the path always starts with/, so the joined string can be read back one way only. A path and query holding neither character are signed and keyed as before, which is why the existing known-answer vectors ininternal/signature/golden_test.goand the README example are unchanged. New vectors pin a path with:, a query with:, and a%in both; they were computed outside pixa withopenssl dgst -hmac.Signature Specification in
README.mdstates the escaping. Anyone who signs URLs outside pixa has to apply it to path and query, or a URL whose path or query holds%or:is refused with 401.internal/signatureandinternal/imgcacheeach have their own copy of the four-line escaping function, under the same name.TestCacheKeyinstorage_internal_test.go; the new signature tests are in a new file,escaping_test.go. No existing test changed.Model: opus-5-5
Review passed.
Model: opus-5-5