Split out of #16 (item 3). The documentation half (warnings in config2py/codecs.py that .pkl/.pickle decode with pickle.loads and must never be used on untrusted bytes) lands in the cloud-sweep PR. This issue tracks the behaviour change.
Problem
decode_by_extension("x.pkl", untrusted_bytes) executes arbitrary code. Anything that routes keys from a remote store through the extension registry is exposed.
Why this was not changed unattended
Removing or gating the decoder changes what decode_by_extension('*.pkl', ...) does for existing callers who round-trip trusted pickles. It is a security-vs-convenience call for the maintainer.
Proposed plan
- Keep the encoder registered. Stop registering the decoder by default.
- Provide
config2py.codecs.enable_pickle_decoding() (registers pickle.loads for .pkl and .pickle with overwrite=True) for callers who trust their data.
- Make the "No decoder registered"
ValueError for .pkl/.pickle point to that function.
- Tests: default decode of
.pkl raises with the hint; after enable_pickle_decoding() it round-trips. Run the dependents gate.
Split out of #16 (item 3). The documentation half (warnings in
config2py/codecs.pythat.pkl/.pickledecode withpickle.loadsand must never be used on untrusted bytes) lands in the cloud-sweep PR. This issue tracks the behaviour change.Problem
decode_by_extension("x.pkl", untrusted_bytes)executes arbitrary code. Anything that routes keys from a remote store through the extension registry is exposed.Why this was not changed unattended
Removing or gating the decoder changes what
decode_by_extension('*.pkl', ...)does for existing callers who round-trip trusted pickles. It is a security-vs-convenience call for the maintainer.Proposed plan
config2py.codecs.enable_pickle_decoding()(registerspickle.loadsfor.pkland.picklewithoverwrite=True) for callers who trust their data.ValueErrorfor.pkl/.picklepoint to that function..pklraises with the hint; afterenable_pickle_decoding()it round-trips. Run the dependents gate.