@@ -93,13 +93,68 @@ module TaintedPath {
9393 |
9494 name = argumentlessMethodName
9595 )
96- or
96+ )
97+ or
98+ // array method calls of interest
99+ exists ( DataFlow:: MethodCallNode mcn , string name | dst = mcn and mcn .calls ( src , name ) |
100+ // A `str.split()` call can either split into path elements (`str.split("/")`) or split by some other string.
97101 name = "split" and
98- not exists ( DataFlow:: Node splitBy | splitBy = mcn .getArgument ( 0 ) |
99- splitBy .mayHaveStringValue ( "/" ) or
100- any ( DataFlow:: RegExpLiteralNode reg | reg .getRoot ( ) .getAMatchedString ( ) = "/" )
101- .flowsTo ( splitBy )
102+ (
103+ if
104+ exists ( DataFlow:: Node splitBy | splitBy = mcn .getArgument ( 0 ) |
105+ splitBy .mayHaveStringValue ( "/" ) or
106+ any ( DataFlow:: RegExpCreationNode reg | reg .getRoot ( ) .getAMatchedString ( ) = "/" )
107+ .flowsTo ( splitBy )
108+ )
109+ then
110+ srclabel .( Label:: PosixPath ) .canContainDotDotSlash ( ) and
111+ dstlabel instanceof Label:: SplitPath
112+ else srclabel = dstlabel
102113 )
114+ or
115+ (
116+ name = "pop" or
117+ name = "shift"
118+ ) and
119+ srclabel instanceof Label:: SplitPath and
120+ dstlabel .( Label:: PosixPath ) .canContainDotDotSlash ( )
121+ or
122+ (
123+ name = "slice" or
124+ name = "splice" or
125+ name = "concat"
126+ ) and
127+ dstlabel instanceof Label:: SplitPath and
128+ srclabel instanceof Label:: SplitPath
129+ or
130+ name = "join" and
131+ mcn .getArgument ( 0 ) .mayHaveStringValue ( "/" ) and
132+ srclabel instanceof Label:: SplitPath and
133+ dstlabel .( Label:: PosixPath ) .canContainDotDotSlash ( )
134+ )
135+ or
136+ // prefix.concat(path)
137+ exists ( DataFlow:: MethodCallNode mcn |
138+ mcn .getMethodName ( ) = "concat" and mcn .getAnArgument ( ) = src
139+ |
140+ dst = mcn and
141+ dstlabel instanceof Label:: SplitPath and
142+ srclabel instanceof Label:: SplitPath
143+ )
144+ or
145+ // reading unknown property of split path
146+ exists ( DataFlow:: PropRead read | read = dst |
147+ src = read .getBase ( ) and
148+ not read .getPropertyName ( ) = "length" and
149+ not exists ( read .getPropertyNameExpr ( ) .getIntValue ( ) ) and
150+ // split[split.length - 1]
151+ not exists ( BinaryExpr binop |
152+ read .getPropertyNameExpr ( ) = binop and
153+ binop .getAnOperand ( ) .getIntValue ( ) = 1 and
154+ binop .getAnOperand ( ) .( PropAccess ) .getPropertyName ( ) = "length"
155+ ) and
156+ srclabel instanceof Label:: SplitPath and
157+ dstlabel .( Label:: PosixPath ) .canContainDotDotSlash ( )
103158 )
104159 }
105160
0 commit comments