Some functions could behave in ways that individual summaries of dataflow and escape are insufficient to capture taint flows, when the body of the function isn't analyzed:
func leak(p *string) {
pkgGlobal = p
}
// in standard library, so taint doesn't see function bodies:
func ok(x string, p *string) {
*p = x
leak(p)
}
func bad(x string, p *string) {
y := "abc"
q := &y
*q = x
leak(q)
}
In this example, ok function doesn't have an issue, because the dataflow notices x flows to p, and the escape notices that p escapes. In the bad function, the dataflow doesn't have any edges (as p is unused), and the escape analysis doesn't report any escapes of arguments, so taint would be lost, even though it can flow to a shared object.
This problem only occurs when the dataflow cannot see the function body; if the taint analysis sees the function body it will see the leak of a tainted value q.
To solve this, some kind of summary that includes the effects of dataflow and escape together seems necessary, i.e. an edge from an argument to a virtual "escaped" node in this case.
Some functions could behave in ways that individual summaries of dataflow and escape are insufficient to capture taint flows, when the body of the function isn't analyzed:
In this example,
ok
function doesn't have an issue, because the dataflow noticesx
flows top
, and the escape notices thatp
escapes. In thebad
function, the dataflow doesn't have any edges (asp
is unused), and the escape analysis doesn't report any escapes of arguments, so taint would be lost, even though it can flow to a shared object.This problem only occurs when the dataflow cannot see the function body; if the taint analysis sees the function body it will see the leak of a tainted value
q
.To solve this, some kind of summary that includes the effects of dataflow and escape together seems necessary, i.e. an edge from an argument to a virtual "escaped" node in this case.