Skip to content

fix(api): refuse request endpoints that ids would reshape - #189

Open
Gabrielpanga wants to merge 2 commits into
masterfrom
fix/encode-path-and-query-params
Open

Gabrielpanga wants to merge 2 commits into
masterfrom
fix/encode-path-and-query-params

Conversation

@Gabrielpanga

@Gabrielpanga Gabrielpanga commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Ids are interpolated into request paths (accounts/${id}, …). An id containing ?, #, .. or an empty value could change the request actually sent. Follow-up to fix(api): URL-encode query string values #184, which encoded query values.
  • One check in createGetRequest and createMutationRequest (assertSafeEndpoint): an endpoint must not contain a query/fragment delimiter, a % sequence, a backslash, whitespace/control characters, a dot segment, or an empty/leading/trailing slash segment. Query parameters always go through params, so no legitimate endpoint has these. Unsafe endpoints throw before any request is made.
  • No call site changes; valid ids are sent byte-for-byte as before. fetchIdentityByItemId now passes itemId through params instead of building identity?itemId=… by hand.
  • Not covered by design: a / inside an id still reads as a path separator (can't be told apart from the template's own slashes at this point).

Test plan

  • build, tests (110): accepted/rejected endpoint table; plain UUID request unchanged; unsafe ids rejected with no request sent; identity itemId sent as an encoded query param

Ids interpolated into request paths were sent as-is, so a value containing
"?", "&", "/" or "#" could change the request that was actually made. Path
values now go through a urlPath tagged template that applies
encodeURIComponent to each interpolated segment, and fetchIdentityByItemId
passes itemId as a query parameter instead of concatenating it into the path.
Plain UUIDs are unchanged on the wire.
…ry path

Replace the urlPath tagged template with one check in createGetRequest and
createMutationRequest: an endpoint built from caller-provided ids must not
contain a query or fragment delimiter, a percent sequence, a backslash,
whitespace or control characters, a dot segment, or an empty, leading or
trailing slash segment. Query parameters always go through params, so no
legitimate endpoint has any of these; the request is refused instead of
being sent with a different shape. Call sites are unchanged, and valid ids
are sent exactly as before. fetchIdentityByItemId passes itemId as a query
parameter.
@Gabrielpanga Gabrielpanga changed the title fix(api): URL-encode path segments built from caller-provided ids fix(api): refuse request endpoints that ids would reshape Oct 13, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant