Python: Expand stdlib decoding tests

The part about claiming there is decoding of the input to `shelve.open`
is sort of an odd one, since it's not the filename, but the contents of
the file that is decoded.

However, trying to only handle this problem through path injection is
not enough -- if a user is able to upload and access files through
`shelve.open` in a path injection safe manner, that still leads to code
execution.

So right now the best way we have of modeling this is to treat the
filename argument as being deserialized...
This commit is contained in:
Rasmus Wriedt Larsen
2021-10-07 21:11:51 +02:00
parent a31bf75169
commit 3592b09d56

View File

@@ -1,10 +1,23 @@
import pickle
import marshal
import shelve
import base64
pickle.load(file_) # $ MISSING: decodeInput=file_ decodeOutput=pickle.load(..) decodeFormat=pickle decodeMayExecuteInput
pickle.load(file=file_) # $ MISSING: decodeInput=file_ decodeOutput=pickle.load(..) decodeFormat=pickle decodeMayExecuteInput
pickle.loads(payload) # $ decodeInput=payload decodeOutput=pickle.loads(..) decodeFormat=pickle decodeMayExecuteInput
# using this keyword argument is disallowed from Python 3.9
pickle.loads(data=payload) # $ decodeOutput=pickle.loads(..) decodeFormat=pickle decodeMayExecuteInput MISSING: decodeInput=payload
marshal.load(file_) # $ MISSING: decodeInput=file_ decodeOutput=marshal.load(..) decodeFormat=marshal decodeMayExecuteInput
marshal.loads(payload) # $ decodeInput=payload decodeOutput=marshal.loads(..) decodeFormat=marshal decodeMayExecuteInput
# if the file opened has been controlled by an attacker, this can lead to code
# execution. (underlying file format is pickle)
shelve.open(filepath) # $ MISSING: decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath
shelve.open(filename=filepath) # $ MISSING: decodeInput=filepath decodeOutput=shelve.open(..) decodeFormat=pickle decodeMayExecuteInput getAPathArgument=filepath
# TODO: These tests should be merged with python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_string.py
base64.b64decode(payload) # $ decodeInput=payload decodeOutput=base64.b64decode(..) decodeFormat=Base64
base64.standard_b64decode(payload) # $ decodeInput=payload decodeOutput=base64.standard_b64decode(..) decodeFormat=Base64