Skip to content

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

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

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