[Python] Taint Analysis for a particular scenario involving StringIO #20085
-
from io import StringIO
dangerous_sink = print
class Source:
def __init__(self, stream: StringIO|None = None):
self.stream = stream if stream is not None else StringIO()
def read(self):
return self.stream.getvalue()
def writecontent(self, content):
self.stream.write(content)
class Processor:
def process(self, s: Source):
s.stream.seek(0)
source_code = s.stream.getvalue()
dangerous_sink(test_global + "" + source_code)
test_global = "test_data"
tainted_global = "tainted_data"
if __name__ == "__main__":
s = Source()
c = Processor()
s.writecontent(tainted_global)
c.process(s) My goal here is to track Note: I don't want to just taint calls to My taint analysis reaches However, tainting I'm not sure how I would go about tainting something in the enclosing scope since this method does not return anything. Below is the current version of my predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::MethodCallNode m|
m.getMethodName() = "write" and
m.getObject() = succ and
pred = m.getArg(0)
)
or
exists(DataFlow::MethodCallNode m |
m.getMethodName() = "write" and
m.getObject() = pred
and pred.asExpr().(Attribute).getObject() = succ.asExpr()
)
or
exists(DataFlow::MethodCallNode m|
m.getMethodName() in ["getvalue", "read"] and
succ = m
and pred = m.getObject()
)
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
You're very close!
(the middle disjunct) is unnecessary and can be removed. The top disjunct needs changing to use
You must also use Finally note these are overly broad models since any method named |
Beta Was this translation helpful? Give feedback.
You're very close!
(the middle disjunct) is unnecessary and can be removed.
The top disjunct needs changing to use
DataFlow::PostUpdateNode
, which represents a side-effect on a function parameter (includingself
, as here):You must also use
TaintTracking
because of the string-concatenation step attest_global + "" + source_code
(…