Refuse an image URL whose source path or query holds a # (closes #286) #287

Merged
clawbot merged 2 commits from issue-286-hash-in-source-path into next 2026-10-16 01:36:57 +02:00
Collaborator

Closes #286.

A # written as %23 in the source path or source query of a /v1/image/ URL reached parseImageComponents decoded and stayed there. The source URL built from it ended at the # when it was fetched, so each text after it fetched the same upstream image (without a signature for an allowlisted host) and cached it under keys of its own. Such a URL is now refused with 400, and the rule in README.md for writing a source path and query says neither may hold a #.

What the diff does not show:

  • The check runs after the host check, so a %23 in the host is still refused as an invalid source host, as #275 made it, and its existing test is unchanged.
  • %2523 is still accepted: it decodes once to %23, which the source URL keeps as part of the path.
  • A signature does not get such a URL through: the URL is refused before its signature is read. One of the new tests signs the exact source path with the # to show it.

The first commit adds the three tests through the image route, which the second makes pass.

Judgement call: the refusal reuses ErrInvalidPath with a reason after it, rather than a new error.
Unverified: the %2523 point is read from the code; no test covers it.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/pixa/issues/286. A `#` written as `%23` in the source path or source query of a `/v1/image/` URL reached `parseImageComponents` decoded and stayed there. The source URL built from it ended at the `#` when it was fetched, so each text after it fetched the same upstream image (without a signature for an allowlisted host) and cached it under keys of its own. Such a URL is now refused with 400, and the rule in `README.md` for writing a source path and query says neither may hold a `#`. What the diff does not show: - The check runs after the host check, so a `%23` in the host is still refused as an invalid source host, as https://git.eeqj.de/sneak/pixa/issues/275 made it, and its existing test is unchanged. - `%2523` is still accepted: it decodes once to `%23`, which the source URL keeps as part of the path. - A signature does not get such a URL through: the URL is refused before its signature is read. One of the new tests signs the exact source path with the `#` to show it. The first commit adds the three tests through the image route, which the second makes pass. Judgement call: the refusal reuses `ErrInvalidPath` with a reason after it, rather than a new error. Unverified: the `%2523` point is read from the code; no test covers it. Model: opus-5-5
clawbot added the needs-review label 2026-10-16 01:22:20 +02:00
clawbot added 2 commits 2026-10-16 01:22:20 +02:00
The image route serves these today: the source URL ends at the #, so
each text after it fetches the same upstream image and caches it under
keys of its own.

Model: opus-5-5
A # written as %23 reached the parser decoded and stayed in the source
path or query. The source URL built from it ended at the # when it was
fetched, so each text after it fetched the same upstream image, without
a signature for an allowlisted host, and cached it under keys of its
own. Such a URL is now refused with 400, and README.md says neither the
source path nor the source query may hold a #.

Model: opus-5-5
clawbot self-assigned this 2026-10-16 01:22:31 +02:00
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit 1fd5cf8bd0 into next 2026-10-16 01:36:57 +02:00
clawbot deleted branch issue-286-hash-in-source-path 2026-10-16 01:36:58 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/pixa#287