Skip to content

URL-encode record keys and request IDs to prevent path traversal #1005

Closed

Description

@vdusek

Problem

The client interpolates record keys, request IDs, and resource IDs directly into request URLs. Values containing /, ?, #, or dot segments can therefore change the target path, query, or fragment.

For example, deleteRecord('..') resolves to the key-value store root and sends DELETE /v2/key-value-stores/{storeId}, potentially deleting the entire store. Other crafted values can target a different endpoint using the caller's token or silently access the wrong record.

This is the JS equivalent of apify/apify-client-python#1025, which has already been fixed.

Cause

_url() uses plain string interpolation:

protected _url(path?: string): string {
    return path ? `${this.url}/${path}` : this.url;
}

Affected values are interpolated in:

  • key_value_store.ts: record operations
  • request_queue.ts: request and lock operations
  • api_client.ts: resource IDs

Additionally, _toSafeId() uses id.replace('/', '~'), which replaces only the first slash.

Expected fix

  • Encode each dynamic path segment with encodeURIComponent() at its call site. Do not encode the complete path, because paths such as requests/batch contain intentional separators.
  • Reject '', . and ..; URL parsers resolve dot segments even when percent-encoded.
  • Keep record signatures based on the raw key, as the server verifies the decoded route parameter.
  • Make _toSafeId() replace every slash, matching the Python client.

Activity

  1. added
    t-toolingIssues with this label are in the ownership of the tooling team.
    on Aug 21, 2026
  2. changed the title [-]Record keys and request IDs are not URL-encoded, allowing path traversal[/-] [+]URL-encode record keys and request IDs to prevent path traversal[/+] on Aug 21, 2026
  3. added a commit that references this issue on Aug 27, 2026
    7a73908
  4. added this to the 3.0 milestone on Sep 4, 2026
  5. vdusek commented on Sep 4, 2026

    @vdusek
    ContributorAuthor

    resolved by #1011

  6. marked Escape/validate URL parameters #96 as a duplicate of this issue on Sep 8, 2026
  7. added a commit that references this issue on Sep 8, 2026
    65a8e66
  8. added a commit that references this issue on Sep 30, 2026
    1967561
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

t-toolingIssues with this label are in the ownership of the tooling team.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions