Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

HttpApiClient: a path parameter of `.` or `..` changes the request path

Closed
#9,766 0 comments 0 reactions 1 assignee View on GitHub

Maintainers usually reply within 1 day

@effect-bot is already working on this.

Since Oct 22, 2026.

Assessment

This issue has not been assessed yet.

Description

HttpApiClient puts each path parameter into the URL with encodeURIComponent. That function leaves . and .. unchanged, so a parameter whose value is . or .. becomes a dot segment. The URL parser then resolves it, and the request goes to a different path than the endpoint's.

const Api = HttpApi.make("Api").add(
  HttpApiGroup.make("users").add(
    HttpApiEndpoint.get("get", "/users/:id", { params: { id: Schema.String } }),
    HttpApiEndpoint.delete("remove", "/users/:id/sessions", { params: { id: Schema.String } })
  )
)

const client = yield* HttpApiClient.make(Api, { baseUrl: "http://127.0.0.1:3000/api/v1" })
yield* client.users.get({ params: { id: ".." } })
yield* client.users.remove({ params: { id: ".." } })

A local node:http server receives these requests, and both FetchHttpClient and NodeHttpClient send the same ones:

id get remove
"." GET /api/v1/users/ DELETE /api/v1/users/sessions
".." GET /api/v1/ DELETE /api/v1/sessions

So an ID that comes from user input can send a DELETE to a different resource. I found this while building a Docker Engine client: containers.inspect({ id: "." }) calls the list endpoint /containers/json. A value like ../admin is safe, because encodeURIComponent encodes the /.

Cause

compilePath builds the URL for both HttpApiClient.make and the URL builder (line 793).

Percent-encoding the dots doesn't help. WHATWG URL also treats %2e, .%2e, %2e. and %2e%2e as dot segments, in either case. For example, new URL("http://x/a/%2E%2E/b").pathname is /b. No encoding of . or .. survives URL, so the client can't send one as a path segment.

Proposal

Reject a path parameter whose value is exactly . or .. before sending the request, the same way a missing required parameter is rejected today. Rust's Docker client bollard does the same for its path parameters.

Whether this should be a defect, like the missing-parameter Error, or a typed failure is a maintainer decision.

Dominant language
TypeScript
Stars
16.7k
Forks
808
Avg merge
11h 24m
Merged PRs (30d)
848

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Effect-TS/effect

All issues in Effect-TS/effect

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.