Add cloudpickle to pickle blacklists (B403/B301) - #1462
Conversation
cloudpickle extends pickle's serialization to arbitrary Python objects, so deserializing untrusted cloudpickle data is an arbitrary-code-execution risk, exactly like pickle/dill. bandit already flags pickle, cPickle, dill, shelve, jsonpickle and pandas.read_pickle but not cloudpickle. - B403: add 'cloudpickle' to the flagged imports. - B301: add cloudpickle.loads / cloudpickle.load / cloudpickle.Unpickler to the flagged calls. - Add examples/cloudpickle.py and a functional test mirroring the dill case (1 LOW import + 3 MEDIUM calls, all HIGH confidence). Closes PyCQA#1236.
noqt
left a comment
There was a problem hiding this comment.
Tested this exact head for NOQT. The load and loads additions work across normal, aliased, and from imports, and serialization-only calls stay clear.
One repair is needed: cloudpickle 3.1.2 explicitly says it has no unpickler, and its public exports include Pickler/CloudPickler, load, and loads—not Unpickler. The new syntax-only example never executes, so cloudpickle.Unpickler(...) looks covered even though that API doesn't exist.
Please remove cloudpickle.Unpickler from the B301 table/config/example and reduce the expected MEDIUM/HIGH counts accordingly. The targeted test passes; the broader file is 78/80 on Windows, with the same two unrelated fixture failures on upstream main. git diff --check passes. The remaining load/loads coverage looks good.
cloudpickle 3.1.2 has no Unpickler class -- its public exports are Pickler/CloudPickler, load, and loads. Drop it from the B301 table, config list, and example; adjust test_cloudpickle's expected counts (MEDIUM 3->2, HIGH confidence 4->3) to match. Addresses review feedback from @noqt on PR PyCQA#1462.
Closes #1236.
What
cloudpickleextendspickleto serialize arbitrary Python objects (lambdas, closures, dynamically-defined classes). That makes deserializing untrusted cloudpickle data an arbitrary-code-execution risk, exactly likepickleanddill— but bandit's pickle blacklists didn't cover it, while they already coverpickle,cPickle,dill,shelve,jsonpickleandpandas.read_pickle.Changes
import_pickle): addcloudpickleto the flagged imports.pickle): addcloudpickle.loads,cloudpickle.load,cloudpickle.Unpicklerto the flagged calls.examples/cloudpickle.py(mirroringexamples/dill.py) and atest_cloudpicklefunctional test.Verification
Findings match the
dillcase exactly — 1 LOW import + 3 MEDIUM calls, all HIGH confidence.test_cloudpicklepasses and the full functional suite is green (80 passed) with no regressions.