@@ -7,6 +7,9 @@ private import Node as Node
77private import Content
88private import FlowSummaryImpl as FlowSummaryImpl
99private import codeql.rust.internal.CachedStages
10+ private import codeql.rust.internal.TypeInference as TypeInference
11+ private import codeql.rust.internal.Type as Type
12+ private import codeql.rust.frameworks.stdlib.Builtins as Builtins
1013
1114module RustTaintTracking implements InputSig< Location , RustDataFlow > {
1215 predicate defaultTaintSanitizer ( DataFlow:: Node node ) { none ( ) }
@@ -40,11 +43,22 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
4043 succ .asExpr ( ) = index
4144 )
4245 or
43- // Although data flow through collections and references is modeled using
44- // stores/reads, we also allow taint to flow out of a tainted collection
45- // or reference.
46- // This is needed in order to support taint-tracking configurations where
47- // the source is a collection or reference.
46+ // Read steps give rise to taint steps. This has the effect that if `foo`
47+ // is tainted and an operation reads from `foo` (e.g., `foo.bar`) then
48+ // taint is propagated. We limit this to not apply if the type of the
49+ // operation is a small primitive type as these are often uninteresting
50+ // (for instance in the case of an injection query).
51+ RustDataFlow:: readContentStep ( pred , _, succ ) and
52+ not exists ( Struct s |
53+ s = TypeInference:: inferType ( succ .asExpr ( ) ) .( Type:: StructType ) .getStruct ( )
54+ |
55+ s instanceof Builtins:: NumericType or
56+ s instanceof Builtins:: Bool or
57+ s instanceof Builtins:: Char
58+ )
59+ or
60+ // Let all read steps (including those from flow summaries and those that
61+ // result in small primitive types) give rise to taint steps.
4862 exists ( SingletonContentSet cs | RustDataFlow:: readStep ( pred , cs , succ ) |
4963 cs .getContent ( ) instanceof ElementContent
5064 or
0 commit comments