feat: include quality and fit in the URL signature (closes #60)
check / check (push) Failing after 1s
check / check (push) Failing after 1s
Quality (q) and fit were read after signature validation and folded into the variant cache key, so one signed URL could be replayed across 100 quality values and 5 fit modes, yielding up to 500 unauthorized cache entries and libvips transcodes. The signed data now appends the effective quality and fit: host:path:query:width:height:format:expiration:quality:fit The handler already defaults an omitted q to 85 and fit to cover before verification, so those effective values are what gets signed; a URL signed for one quality or fit no longer verifies when replayed with another. This is a breaking change to the URL signing scheme: external signers must append :<quality>:<fit> to the signed string. New known-answer vectors are added in golden_qualityfit_test.go; the README signature specification is updated. The pre-existing golden_test.go pins the old signed bytes and can no longer stay green; it is left unedited per instruction pending an owner decision. model: claude-opus-4-8
This commit is contained in:
@@ -75,7 +75,7 @@ or partial matching is supported.
|
||||
**Signed data format** (colon-separated):
|
||||
|
||||
```
|
||||
HMAC-SHA256(secret, "host:path:query:width:height:format:expiration")
|
||||
HMAC-SHA256(secret, "host:path:query:width:height:format:expiration:quality:fit")
|
||||
```
|
||||
|
||||
Where:
|
||||
@@ -87,13 +87,20 @@ Where:
|
||||
- `height` — requested height in pixels, `0` for original
|
||||
- `format` — output format (jpeg, png, webp, avif, gif, orig)
|
||||
- `expiration` — Unix timestamp when signature expires
|
||||
- `quality` — output quality 1-100; sign `85` (the default) when the URL
|
||||
omits the `q` parameter
|
||||
- `fit` — fit mode (cover, contain, fill, inside, outside); sign `cover`
|
||||
(the default) when the URL omits the `fit` parameter
|
||||
|
||||
**Example:** resize
|
||||
`https://cdn.example.com/photos/cat.jpg` to 800x600 WebP with
|
||||
expiration 1704067200:
|
||||
The `q` and `fit` query parameters are covered by the signature. A URL
|
||||
signed for one quality or fit value will not verify when replayed with a
|
||||
different value; the effective (post-default) value is what is signed.
|
||||
|
||||
**Example:** resize `https://cdn.example.com/photos/cat.jpg` to 800x600
|
||||
WebP with expiration 1704067200, default quality and fit:
|
||||
|
||||
1. Build input:
|
||||
`cdn.example.com:/photos/cat.jpg::800:600:webp:1704067200`
|
||||
`cdn.example.com:/photos/cat.jpg::800:600:webp:1704067200:85:cover`
|
||||
2. Compute HMAC-SHA256 with your secret key
|
||||
3. Base64URL-encode the result
|
||||
4. URL:
|
||||
|
||||
Reference in New Issue
Block a user