JS: Do not include taint steps in TaintedUrlSuffix::step

TaintedUrlSuffix is currently only used in TaintTracking configs meaning it is already propagated
by taint steps. The inclusion of these taint steps here however meant that implicit reads could appear prior to any of these steps.

This was is problematic for PropRead steps as an expression like x[0] could spuriously read from array element 1 via the path:

x [element 1]
x [empty access path] (after implicit read)
x[0] (taint step through PropRead)
This commit is contained in:
Asger F
2024-09-11 15:38:39 +02:00
parent 2712bf821a
commit 74ab346348
2 changed files with 2 additions and 18 deletions

View File

@@ -36,16 +36,6 @@ module TaintedUrlSuffix {
result.getKind().isUrl()
}
/** Holds for `pred -> succ` is a step of form `x -> x.p` */
private predicate isSafeLocationProp(DataFlow::PropRead read) {
// Ignore properties that refer to the scheme, domain, port, auth, or path.
read.getPropertyName() =
[
"protocol", "scheme", "host", "hostname", "domain", "origin", "port", "path", "pathname",
"username", "password", "auth"
]
}
/**
* Holds if `node` should be a barrier for the given `label`.
*
@@ -63,12 +53,6 @@ module TaintedUrlSuffix {
* This handles steps through string operations, promises, URL parsers, and URL accessors.
*/
predicate step(Node src, Node dst, FlowLabel srclbl, FlowLabel dstlbl) {
// Inherit all ordinary taint steps except `x -> x.p` steps
srclbl = label() and
dstlbl = label() and
TaintTracking::AdditionalTaintStep::step(src, dst) and
not isSafeLocationProp(dst)
or
srclbl = label() and
dstlbl.isTaint() and
DataFlowPrivate::optionalStep(src, "tainted-url-suffix", dst)

View File

@@ -8,12 +8,12 @@ function t1() {
sink(href.split('#')[0]); // $ MISSING: flow=tainted-url-suffix
sink(href.split('#')[1]); // $ flow=taint
sink(href.split('#').pop()); // $ flow=taint
sink(href.split('#')[2]); // $ flow=taint
sink(href.split('#')[2]); // $ MISSING: flow=taint // currently the split() summary only propagates to index 1
sink(href.split('?')[0]); // $ MISSING: flow=tainted-url-suffix
sink(href.split('?')[1]); // $ flow=taint
sink(href.split('?').pop()); // $ flow=taint
sink(href.split('?')[2]); // $ flow=taint
sink(href.split('?')[2]); // $ MISSING: flow=taint
sink(href.split(blah())[0]); // $ flow=tainted-url-suffix
sink(href.split(blah())[1]); // $ flow=tainted-url-suffix