@@ -213,17 +213,51 @@ module TaintedPath {
213213 output = this
214214 )
215215 or
216- // non-global replace or replace of something other than /\.\./g
216+ // non-global replace or replace of something other than /\.\./g, /[/]/g, or /[\.]/g.
217217 this .getCalleeName ( ) = "replace" and
218218 input = getReceiver ( ) and
219219 output = this and
220- not exists ( RegExpLiteral literal , RegExpSequence seq |
220+ not exists ( RegExpLiteral literal , RegExpTerm term |
221221 getArgument ( 0 ) .getALocalSource ( ) .asExpr ( ) = literal and
222222 literal .isGlobal ( ) and
223- literal .getRoot ( ) = seq and
224- seq .getChild ( 0 ) .( RegExpConstant ) .getValue ( ) = "." and
225- seq .getChild ( 1 ) .( RegExpConstant ) .getValue ( ) = "." and
226- seq .getNumChild ( ) = 2
223+ literal .getRoot ( ) = term
224+ |
225+ term .getAMatchedString ( ) = "/" or
226+ term .getAMatchedString ( ) = "." or
227+ term .getAMatchedString ( ) = ".."
228+ )
229+ }
230+
231+ /**
232+ * Gets the input path to be normalized.
233+ */
234+ DataFlow:: Node getInput ( ) { result = input }
235+
236+ /**
237+ * Gets the normalized path.
238+ */
239+ DataFlow:: Node getOutput ( ) { result = output }
240+ }
241+
242+ /**
243+ * A call that removes all "." or ".." from a path, without also removing all forward slashes.
244+ */
245+ class DotRemovingReplaceCall extends DataFlow:: CallNode {
246+ DataFlow:: Node input ;
247+ DataFlow:: Node output ;
248+
249+ DotRemovingReplaceCall ( ) {
250+ this .getCalleeName ( ) = "replace" and
251+ input = getReceiver ( ) and
252+ output = this and
253+ exists ( RegExpLiteral literal , RegExpTerm term |
254+ getArgument ( 0 ) .getALocalSource ( ) .asExpr ( ) = literal and
255+ literal .isGlobal ( ) and
256+ literal .getRoot ( ) = term and
257+ not term .getAMatchedString ( ) = "/"
258+ |
259+ term .getAMatchedString ( ) = "." or
260+ term .getAMatchedString ( ) = ".."
227261 )
228262 }
229263
0 commit comments