@@ -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 ( ) }
@@ -51,6 +54,20 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
5154 cs .getContent ( ) instanceof ReferenceContent
5255 )
5356 or
57+ // Lift read steps as taint steps. This has the effect that if `foo` is
58+ // tainted and an operation reads from `foo`, for instance `foo.bar`, then
59+ // the operation will carry taint as well. We limit this to not lift
60+ // reads if the type being read is not a small primitive type. These are
61+ // often uninteresting, for instance in the case of injection queries.
62+ RustDataFlow:: readContentStep ( pred , _, succ ) and
63+ not exists ( Struct s |
64+ s = TypeInference:: inferType ( succ .asExpr ( ) ) .( Type:: StructType ) .getStruct ( )
65+ |
66+ s instanceof Builtins:: NumericType or
67+ s instanceof Builtins:: Bool or
68+ s instanceof Builtins:: Char
69+ )
70+ or
5471 exists ( FormatArgsExpr format | succ .asExpr ( ) = format |
5572 pred .asExpr ( ) = format .getAnArg ( ) .getExpr ( )
5673 or
0 commit comments