@@ -79,6 +79,47 @@ private module UnicodeBypassValidationConfig implements DataFlow::StateConfigSig
7979
8080 predicate isSource ( DataFlow:: Node source , FlowState state ) {
8181 source instanceof RemoteFlowSource and state = PreValidationState ( )
82+ or
83+ (
84+ exists ( Escaping escaping | source = escaping .getOutput ( ) )
85+ or
86+ exists ( RegexExecution re | source = re )
87+ or
88+ // String Manipulation Method Calls
89+ // https://ruby-doc.org/core-2.7.0/String.html
90+ // String Manipulation Method Calls
91+ // https://ruby-doc.org/core-2.7.0/String.html
92+ exists ( DataFlow:: CallNode cn |
93+ cn .getMethodName ( ) =
94+ [
95+ [
96+ "ljust" , "lstrip" , "succ" , "next" , "rjust" , "capitalize" , "chomp" , "gsub" , "chop" ,
97+ "downcase" , "swapcase" , "uprcase" , "scrub" , "slice" , "squeeze" , "strip" , "sub" ,
98+ "tr" , "tr_s" , "reverse"
99+ ] + [ "" , "!" ] , "concat" , "dump" , "each_line" , "replace" , "insert" , "inspect" , "lines" ,
100+ "partition" , "prepend" , "replace" , "rpartition" , "scan" , "split" , "undump" ,
101+ "unpack" + [ "" , "1" ]
102+ ] and
103+ source = cn and
104+ source .getLocation ( ) .getFile ( ) .getBaseName ( ) .matches ( "object.rb" )
105+ )
106+ or
107+ exists ( DataFlow:: CallNode cn |
108+ cn .getMethodName ( ) =
109+ [
110+ "casecmp" + [ "" , "?" ] , "center" , "count" , "each_char" , "index" , "rindex" , "sum" ,
111+ [ "delete" , "delete_prefix" , "delete_suffix" ] + [ "" , "!" ] ,
112+ [ "start_with" , "end_with" + "eql" , "include" ] + [ "?" , "!" ] , "match" + [ "" , "?" ] ,
113+ ] and
114+ source = cn .getReceiver ( )
115+ )
116+ or
117+ exists ( DataFlow:: CallNode cn |
118+ cn = API:: getTopLevelMember ( "CGI" ) .getAMethodCall ( "escapeHTML" ) and
119+ source = cn
120+ )
121+ ) and
122+ state = PostValidationState ( )
82123 }
83124
84125 predicate isAdditionalFlowStep (
0 commit comments