@@ -59,17 +59,52 @@ module LogInjection {
5959 }
6060 }
6161
62+ /**
63+ * A call to `strings.NewReplacer`.
64+ */
65+ class StringsNewReplacerCall extends DataFlow:: CallNode {
66+ StringsNewReplacerCall ( ) { this .getTarget ( ) .hasQualifiedName ( "strings" , "NewReplacer" ) }
67+
68+ /**
69+ * Gets an argument to this call corresponding to a string that will be
70+ * replaced.
71+ */
72+ DataFlow:: Node getAReplacedArgument ( ) { exists ( int n | n % 2 = 0 and result = getArgument ( n ) ) }
73+ }
74+
75+ /**
76+ * A configuration for tracking flow from a call to `strings.NewReplacer` to
77+ * the receiver of a call to `strings.Replacer.Replace` or
78+ * `strings.Replacer.WriteString`.
79+ */
80+ class StringsNewReplacerConfiguration extends DataFlow2:: Configuration {
81+ StringsNewReplacerConfiguration ( ) { this = "StringsNewReplacerConfiguration" }
82+
83+ override predicate isSource ( DataFlow:: Node source ) { source instanceof StringsNewReplacerCall }
84+
85+ override predicate isSink ( DataFlow:: Node sink ) {
86+ exists ( DataFlow:: MethodCallNode call |
87+ sink = call .getReceiver ( ) and
88+ call .getTarget ( ) .hasQualifiedName ( "strings" , "Replacer" , [ "Replace" , "WriteString" ] )
89+ )
90+ }
91+ }
92+
6293 /**
6394 * A call to `strings.Replacer.Replace`, considered as a sanitizer for log
6495 * injection.
6596 */
6697 class ReplacerReplaceSanitizer extends Sanitizer {
6798 ReplacerReplaceSanitizer ( ) {
68- exists ( DataFlow:: MethodCallNode call |
69- call .( DataFlow:: MethodCallNode )
70- .getTarget ( )
71- .hasQualifiedName ( "strings" , "Replacer" , "Replace" ) and
72- this = call .getResult ( )
99+ exists (
100+ StringsNewReplacerConfiguration config , DataFlow:: Node source , DataFlow:: Node sink ,
101+ DataFlow:: MethodCallNode call
102+ |
103+ config .hasFlow ( source , sink ) and
104+ call .getTarget ( ) .hasQualifiedName ( "strings" , "Replacer" , "Replace" ) and
105+ sink = call .getReceiver ( ) and
106+ this = call .getResult ( ) and
107+ source .( StringsNewReplacerCall ) .getAReplacedArgument ( ) .getStringValue ( ) = [ "\r" , "\n" ]
73108 )
74109 }
75110 }
@@ -80,9 +115,15 @@ module LogInjection {
80115 */
81116 class ReplacerWriteStringSanitizer extends Sanitizer {
82117 ReplacerWriteStringSanitizer ( ) {
83- exists ( DataFlow:: MethodCallNode call |
118+ exists (
119+ StringsNewReplacerConfiguration config , DataFlow:: Node source , DataFlow:: Node sink ,
120+ DataFlow:: MethodCallNode call
121+ |
122+ config .hasFlow ( source , sink ) and
84123 call .getTarget ( ) .hasQualifiedName ( "strings" , "Replacer" , "WriteString" ) and
85- this = call .getArgument ( 1 )
124+ sink = call .getReceiver ( ) and
125+ this = call .getArgument ( 1 ) and
126+ source .( StringsNewReplacerCall ) .getAReplacedArgument ( ) .getStringValue ( ) = [ "\r" , "\n" ]
86127 )
87128 }
88129 }
0 commit comments