Skip to content

fix: never unpickle binary request bodies unless explicitly asked - #20

Merged
thorwhalen merged 2 commits into
masterfrom
py2http-refuse-pickle-input
Sep 22, 2026
Merged

thorwhalen merged 2 commits into
masterfrom
py2http-refuse-pickle-input

Conversation

@thorwhalen

@thorwhalen thorwhalen commented Sep 22, 2026

Copy link
Copy Markdown
Member

Addresses item 1 of #18 (server side).

What changes

  • handle_binary_req(func, *, loads): the body decoder is now a required keyword-only argument. Calling handle_binary_req(func) raises TypeError at decoration time with a message explaining why and how to opt in.
  • New unsafe_pickle_loads: the explicit, loudly named opt-in for services whose clients are all trusted (handle_binary_req(func, loads=unsafe_pickle_loads)).
  • _get_inputs_from_request never unpickles on its own; with no decoder it raises, and the decoded body must be a mapping.
  • Passing loads=pickle.loads directly still works but emits a warning pointing at unsafe_pickle_loads.
  • Tests in py2http/tests/test_binary_req.py, including an end-to-end check that a default service answers an octet-stream pickle body with an error and without unpickling it.

Compatibility

Breaking only for code that called handle_binary_req(func) without arguments. Fleet dependents of py2http (extrude, peruse) do not use it (checked by search); their test suites were run against this branch; the only failures are unrelated import errors (missing optional modules, stale internal names). send_binary_resp / binary_output (server pickling responses) are unchanged.

Review

Independent refute-review by a sub-agent: no blockers. Applied: warning on bare pickle.loads, Optional annotation, explicit doctest +ELLIPSIS, tighter test assertions, end-to-end test, docstring note that http2py clients send pickle.

Not in this PR

  • Item 2 of Restrict binary (pickle) input and '*' attribute dispatch #18 (attr_names='*' dispatch) — left for a separate change.
  • Client side: http2py still unpickles binary responses and sends pickled binary requests; that belongs in the http2py repo.
  • JWT middleware option naming noticed during review (verify vs verify_signature); separate follow-up.

🤖 Generated with Claude Code

thorwhalen and others added 2 commits September 22, 2026 16:09
handle_binary_req now takes a keyword-only `loads` (bytes -> mapping of
inputs) and raises at decoration time when it is not given. Unpickling is
still available as an explicit opt-in, `loads=unsafe_pickle_loads`, for
services whose clients are all trusted. The decoded body must be a mapping.

Refs #18 (item 1, server side).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thorwhalen
thorwhalen merged commit 899e3d0 into master Sep 22, 2026
6 checks passed
@thorwhalen
thorwhalen deleted the py2http-refuse-pickle-input branch September 22, 2026 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant