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.
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 sendsDELETE /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:Affected values are interpolated in:
key_value_store.ts: record operationsrequest_queue.ts: request and lock operationsapi_client.ts: resource IDsAdditionally,
_toSafeId()usesid.replace('/', '~'), which replaces only the first slash.Expected fix
encodeURIComponent()at its call site. Do not encode the complete path, because paths such asrequests/batchcontain intentional separators.'',.and..; URL parsers resolve dot segments even when percent-encoded._toSafeId()replace every slash, matching the Python client.