Repository navigation
Commit 3e333a0
authored
fix: percent-encode caller-supplied URL path segments (#1025)
Caller-supplied values were interpolated into the request path with a
plain f-string, so they could restructure the URL. Reproduced against a
mock server, reading the raw request line:
```
key='../../actor-runs/VICTIM/abort' -> /v2/key-value-stores/actor-runs/VICTIM/abort
request_id='../../../datasets/V/items' -> /v2/datasets/V/items
key='foo?injected=1' -> /v2/.../records/foo?injected=1?attachment=true
key='foo#frag' -> /v2/.../records/foo (fragment dropped, wrong record, no error)
```
Requests carry the caller's token, so traversal acts with full
privileges. The `#` case is a plain correctness bug: any app forwarding
user strings as record keys silently reads the wrong one.
## Fix
New `to_path_segment()` in `_utils/http.py`, applied to the
caller-supplied segment at every `records/{key}` and
`requests/{request_id}` call site, plus `resource_id` in
`ResourceClientBase._resource_url`. `_build_url` itself is untouched, so
literal paths like `requests/batch` keep their separator.
The API routes these as a single Express param (`records/:recordKey`)
and decodes it once, so percent-encoding is what it expects — an
unencoded `/` never matched. Signatures stay over the raw key, which is
what the server verifies against (`key_value_stores.ts:503` HMACs the
decoded `req.params.recordKey`).
## Behavior change
`''`, `.` and `..` now raise `ValueError`. Encoding cannot protect them
— a URL parser resolves dot segments *after* decoding, so
`records/%2E%2E` collapses exactly like `records/..`. They previously
reached the parent endpoint, where the same verb means something else:
- `delete_record('..')` → `DELETE /v2/key-value-stores/{id}`, deleting
the whole store
- `get_record('..')` returned store metadata as record content
- `client.dataset('..')` → `GET /v2/`
Also newly rejected: a non-`str` key, previously coerced by the
f-string. A caller who pre-encoded keys as a workaround now gets double
encoding — but such keys never resolved anyway, since the platform's key
charset forbids both `/` and `%`.
*✍️ Drafted by Claude Code*1 parent 697f8fe commit 3e333a0
6 files changed
Lines changed: 527 additions & 30 deletions
File tree
- src/apify_client
- _resource_clients
- _utils
- tests/unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| |||
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
78 | | - | |
| 78 | + | |
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
239 | 239 | | |
240 | 240 | | |
241 | 241 | | |
242 | | - | |
| 242 | + | |
243 | 243 | | |
244 | 244 | | |
245 | 245 | | |
| |||
270 | 270 | | |
271 | 271 | | |
272 | 272 | | |
273 | | - | |
| 273 | + | |
274 | 274 | | |
275 | 275 | | |
276 | 276 | | |
| |||
298 | 298 | | |
299 | 299 | | |
300 | 300 | | |
301 | | - | |
| 301 | + | |
302 | 302 | | |
303 | 303 | | |
304 | 304 | | |
| |||
334 | 334 | | |
335 | 335 | | |
336 | 336 | | |
337 | | - | |
| 337 | + | |
338 | 338 | | |
339 | 339 | | |
340 | 340 | | |
| |||
390 | 390 | | |
391 | 391 | | |
392 | 392 | | |
393 | | - | |
| 393 | + | |
394 | 394 | | |
395 | 395 | | |
396 | 396 | | |
| |||
408 | 408 | | |
409 | 409 | | |
410 | 410 | | |
411 | | - | |
| 411 | + | |
412 | 412 | | |
413 | 413 | | |
414 | 414 | | |
| |||
430 | 430 | | |
431 | 431 | | |
432 | 432 | | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
433 | 436 | | |
434 | 437 | | |
435 | 438 | | |
436 | 439 | | |
| 440 | + | |
437 | 441 | | |
438 | 442 | | |
439 | 443 | | |
440 | | - | |
| 444 | + | |
441 | 445 | | |
442 | 446 | | |
443 | 447 | | |
| |||
666 | 670 | | |
667 | 671 | | |
668 | 672 | | |
669 | | - | |
| 673 | + | |
670 | 674 | | |
671 | 675 | | |
672 | 676 | | |
| |||
697 | 701 | | |
698 | 702 | | |
699 | 703 | | |
700 | | - | |
| 704 | + | |
701 | 705 | | |
702 | 706 | | |
703 | 707 | | |
| |||
727 | 731 | | |
728 | 732 | | |
729 | 733 | | |
730 | | - | |
| 734 | + | |
731 | 735 | | |
732 | 736 | | |
733 | 737 | | |
| |||
763 | 767 | | |
764 | 768 | | |
765 | 769 | | |
766 | | - | |
| 770 | + | |
767 | 771 | | |
768 | 772 | | |
769 | 773 | | |
| |||
819 | 823 | | |
820 | 824 | | |
821 | 825 | | |
822 | | - | |
| 826 | + | |
823 | 827 | | |
824 | 828 | | |
825 | 829 | | |
| |||
837 | 841 | | |
838 | 842 | | |
839 | 843 | | |
840 | | - | |
| 844 | + | |
841 | 845 | | |
842 | 846 | | |
843 | 847 | | |
| |||
859 | 863 | | |
860 | 864 | | |
861 | 865 | | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
862 | 869 | | |
863 | 870 | | |
864 | 871 | | |
865 | 872 | | |
| 873 | + | |
866 | 874 | | |
867 | 875 | | |
868 | 876 | | |
869 | | - | |
| 877 | + | |
870 | 878 | | |
871 | 879 | | |
872 | 880 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| |||
275 | 275 | | |
276 | 276 | | |
277 | 277 | | |
278 | | - | |
| 278 | + | |
279 | 279 | | |
280 | 280 | | |
281 | 281 | | |
| |||
300 | 300 | | |
301 | 301 | | |
302 | 302 | | |
303 | | - | |
| 303 | + | |
304 | 304 | | |
305 | 305 | | |
306 | 306 | | |
307 | 307 | | |
308 | 308 | | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
309 | 312 | | |
310 | 313 | | |
311 | 314 | | |
312 | 315 | | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
313 | 319 | | |
314 | 320 | | |
315 | 321 | | |
316 | | - | |
| 322 | + | |
317 | 323 | | |
318 | 324 | | |
319 | 325 | | |
| |||
337 | 343 | | |
338 | 344 | | |
339 | 345 | | |
340 | | - | |
| 346 | + | |
341 | 347 | | |
342 | 348 | | |
343 | 349 | | |
| |||
368 | 374 | | |
369 | 375 | | |
370 | 376 | | |
371 | | - | |
| 377 | + | |
372 | 378 | | |
373 | 379 | | |
374 | 380 | | |
| |||
396 | 402 | | |
397 | 403 | | |
398 | 404 | | |
399 | | - | |
| 405 | + | |
400 | 406 | | |
401 | 407 | | |
402 | 408 | | |
| |||
802 | 808 | | |
803 | 809 | | |
804 | 810 | | |
805 | | - | |
| 811 | + | |
806 | 812 | | |
807 | 813 | | |
808 | 814 | | |
| |||
825 | 831 | | |
826 | 832 | | |
827 | 833 | | |
828 | | - | |
| 834 | + | |
829 | 835 | | |
830 | 836 | | |
831 | 837 | | |
832 | 838 | | |
833 | 839 | | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
834 | 843 | | |
835 | 844 | | |
836 | 845 | | |
837 | 846 | | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
838 | 850 | | |
839 | 851 | | |
840 | 852 | | |
841 | | - | |
| 853 | + | |
842 | 854 | | |
843 | 855 | | |
844 | 856 | | |
| |||
860 | 872 | | |
861 | 873 | | |
862 | 874 | | |
863 | | - | |
| 875 | + | |
864 | 876 | | |
865 | 877 | | |
866 | 878 | | |
| |||
891 | 903 | | |
892 | 904 | | |
893 | 905 | | |
894 | | - | |
| 906 | + | |
895 | 907 | | |
896 | 908 | | |
897 | 909 | | |
| |||
919 | 931 | | |
920 | 932 | | |
921 | 933 | | |
922 | | - | |
| 934 | + | |
923 | 935 | | |
924 | 936 | | |
925 | 937 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
30 | 55 | | |
31 | 56 | | |
32 | 57 | | |
| |||
0 commit comments