This page documents less straightforward bits of Pysa.
are defined via attributes, which are converted to properties under the hood. If
you want to taint the attributes of a
dataclass, you might try to do the
# tainted.py class MyDataClass: attribute: str = ""
# stubs/taint/tainted.py.pysa # This won't work tainted.MyDataClass.attribute: TaintSource[SensitiveData]
This doesn't work, because during analysis Pysa's understanding of the data class is of how the class looks after the property is expanded; that is:
# Pysa's view of tainted.py class MyDataClass: def attribute(self) -> str: ... def attribute(self, value) -> None: ...
Therefore, to annotate a
dataclass attribute, you can use the
# stubs/taint/tainted.py.pysa def tainted.MyDataClass.attribute(self) -> TaintSource[SensitiveData]: ...
Sometimes, a function can have potential sinks mixed together with benign
parameters in the keyword arguments (
kwargs) that it accepts. In these cases,
tainting the whole
kwargs variable will result in false positives when tainted
data flows into a benign
kwarg. Instead, for a function like this:
def eval_and_log(**kwargs): eval(kwargs["eval"]) logging.debug(kwargs["log"])
We can lie a bit in our
.pysa file, and break out the dangerous argument for
def eval_and_log(*, eval: TaintSink[RemoteCodeExecution], **kwargs): ...
This allows us to catch flows only into the
eval keyword argument.
Prevent Inferring Models with
In addition to the models defined in
.pysa files, Pysa will infer models for
functions based what sources, sinks, etc. they call in their body. The
SkipAnalysis annotation can be used to prevent Pysa from inferring models, and
instead force it to use only the user defined models for determining taint flow:
def qualifier.dont_generate_models(argument) -> SkipAnalysis: ...