@@ -44,8 +44,9 @@ private class TypeType extends RefType {
4444 }
4545}
4646
47- /** A sanitizer that may remove sensitive information from a string before logging.
48- *
47+ /**
48+ * A sanitizer that may remove sensitive information from a string before logging.
49+ *
4950 * It allows for substring operations taking the first N (or last N, for Kotlin) characters, limited to 7 or fewer.
5051 */
5152private class SensitiveLoggerSanitizerCalled extends SensitiveLoggerBarrier {
@@ -65,7 +66,8 @@ private class SensitiveLoggerSanitizerCalled extends SensitiveLoggerBarrier {
6566 or
6667 // Kotlin string operations, which use extension methods (so the string is the first argument)
6768 (
68- m .hasQualifiedName ( "kotlin.text" , "StringsKt" , "substring" ) and twoArgLimit ( mc , limit , true )
69+ m .hasQualifiedName ( "kotlin.text" , "StringsKt" , "substring" ) and
70+ twoArgLimit ( mc , limit , true )
6971 or
7072 m .hasQualifiedName ( "kotlin.text" , "StringsKt" , [ "take" , "takeLast" ] ) and
7173 singleArgLimit ( mc , limit , true )
@@ -76,15 +78,18 @@ private class SensitiveLoggerSanitizerCalled extends SensitiveLoggerBarrier {
7678 }
7779}
7880
81+ /** A predicate to check single-argument method calls for a constant integer below a set limit. */
7982bindingset [ limit, isKotlin]
80- predicate singleArgLimit ( MethodCall mc , int limit , boolean isKotlin ) {
83+ private predicate singleArgLimit ( MethodCall mc , int limit , boolean isKotlin ) {
8184 exists ( int argIndex , int staticInt |
8285 ( if isKotlin = true then argIndex = 1 else argIndex = 0 ) and
8386 (
8487 staticInt <= limit and
8588 staticInt > 0 and
86- mc .getArgument ( argIndex ) .getUnderlyingExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) = staticInt
87- or exists ( CompileTimeConstantExpr cte , DataFlow:: Node source , DataFlow:: Node sink |
89+ mc .getArgument ( argIndex ) .getUnderlyingExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) =
90+ staticInt
91+ or
92+ exists ( CompileTimeConstantExpr cte , DataFlow:: Node source , DataFlow:: Node sink |
8893 source .asExpr ( ) = cte and
8994 cte .getIntValue ( ) = staticInt and
9095 sink .asExpr ( ) = mc .getArgument ( argIndex ) and
@@ -94,21 +99,23 @@ predicate singleArgLimit(MethodCall mc, int limit, boolean isKotlin) {
9499 )
95100}
96101
102+ /** A predicate to check two-argument method calls for zero and a constant integer below a set limit. */
97103bindingset [ limit, isKotlin]
98- predicate twoArgLimit ( MethodCall mc , int limit , boolean isKotlin ) {
104+ private predicate twoArgLimit ( MethodCall mc , int limit , boolean isKotlin ) {
99105 exists ( int firstArgIndex , int secondArgIndex , int staticInt |
100106 staticInt <= limit and
101107 staticInt > 0 and
102108 (
103- ( isKotlin = true and firstArgIndex = 1 and secondArgIndex = 2 )
109+ isKotlin = true and firstArgIndex = 1 and secondArgIndex = 2
104110 or
105- ( isKotlin = false and firstArgIndex = 0 and secondArgIndex = 1 )
106- )
107- and
111+ isKotlin = false and firstArgIndex = 0 and secondArgIndex = 1
112+ ) and
108113 mc .getArgument ( firstArgIndex ) .getUnderlyingExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) = 0 and
109114 (
110- mc .getArgument ( secondArgIndex ) .getUnderlyingExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) = staticInt
111- or exists ( CompileTimeConstantExpr cte , DataFlow:: Node source , DataFlow:: Node sink |
115+ mc .getArgument ( secondArgIndex ) .getUnderlyingExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) =
116+ staticInt
117+ or
118+ exists ( CompileTimeConstantExpr cte , DataFlow:: Node source , DataFlow:: Node sink |
112119 source .asExpr ( ) = cte and
113120 cte .getIntValue ( ) = staticInt and
114121 sink .asExpr ( ) = mc .getArgument ( secondArgIndex ) and
@@ -118,7 +125,8 @@ predicate twoArgLimit(MethodCall mc, int limit, boolean isKotlin) {
118125 )
119126}
120127
121- module IntegerToArgConfig implements DataFlow:: ConfigSig {
128+ /** A data-flow configuration for identifying flow from a constant integer to a use in a method argument. */
129+ private module IntegerToArgConfig implements DataFlow:: ConfigSig {
122130 predicate isSource ( DataFlow:: Node source ) {
123131 source .asExpr ( ) .getUnderlyingExpr ( ) instanceof CompileTimeConstantExpr and
124132 source .asExpr ( ) .getType ( ) instanceof IntegralType and
@@ -127,8 +135,8 @@ module IntegerToArgConfig implements DataFlow::ConfigSig {
127135
128136 predicate isSink ( DataFlow:: Node sink ) {
129137 exists ( MethodCall mc |
130- sink .asExpr ( ) = mc .getAnArgument ( )
131- and sink .asExpr ( ) .getType ( ) instanceof IntegralType
138+ sink .asExpr ( ) = mc .getAnArgument ( ) and
139+ sink .asExpr ( ) .getType ( ) instanceof IntegralType
132140 )
133141 }
134142
@@ -159,4 +167,5 @@ module SensitiveLoggerConfig implements DataFlow::ConfigSig {
159167}
160168
161169module SensitiveLoggerFlow = TaintTracking:: Global< SensitiveLoggerConfig > ;
170+
162171module IntegerToArgFlow = TaintTracking:: Global< IntegerToArgConfig > ;
0 commit comments