@@ -34,30 +34,16 @@ module ZipSlip {
3434 }
3535
3636 /**
37- * Holds if `node1` flows to `node2` in one step by virtue of
38- * `node2` being of the form `.pipe(node1)`. The reason this flow
39- * exists is that `.pipe` returns its argument to make chained
40- * stream operations work.
37+ * Gets a node that can be a parsed zip archive.
4138 */
42- predicate pipeStep ( DataFlow:: Node node1 , DataFlow:: MethodCallNode node2 ) {
43- node2 .getMethodName ( ) = "pipe" and
44- node1 = node2 .getArgument ( 0 )
45- }
46-
47- /**
48- * Holds if `node1` flows to `node2` in one step including the assumption that
49- * `x` flows to `.pipe(x)`
50- */
51- predicate stepsThroughPipe ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
52- DataFlow:: localFlowStep ( node1 , node2 ) or pipeStep ( node1 , node2 )
53- }
54-
55- /**
56- * Holds if `node1` flows to `node2` including the assumption that
57- * `x` flows to `.pipe(x)`
58- */
59- predicate flowsThroughPipe ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
60- stepsThroughPipe * ( node1 , node2 )
39+ DataFlow:: SourceNode parsedArchive ( ) {
40+ result = DataFlow:: moduleImport ( "unzip" ) .getAMemberCall ( "Parse" )
41+ or
42+ // `streamProducer.pipe(unzip.Parse())` is a typical (but not
43+ // universal) pattern when using nodejs streams, whose return
44+ // value is the parsed stream.
45+ exists ( DataFlow:: MethodCallNode pipe | pipe .getMethodName ( ) = "pipe"
46+ and parsedArchive ( ) .flowsTo ( pipe .getArgument ( 0 ) ) )
6147 }
6248
6349 /**
@@ -77,11 +63,7 @@ module ZipSlip {
7763 */
7864 class UnzipEntrySource extends Source {
7965 UnzipEntrySource ( ) {
80- exists ( DataFlow:: SourceNode parsed |
81- flowsThroughPipe ( DataFlow:: moduleImport ( "unzip" ) .getAMemberCall ( "Parse" ) , parsed )
82- and
83- this = parsed .getAMemberCall ( "on" ) .getCallback ( 1 ) .getParameter ( 0 ) .getAPropertyRead ( "path" )
84- )
66+ this = parsedArchive ( ) .getAMemberCall ( "on" ) .getCallback ( 1 ) .getParameter ( 0 ) .getAPropertyRead ( "path" )
8567 }
8668 }
8769
@@ -107,7 +89,7 @@ module ZipSlip {
10789 * Gets a string which suffices to search for to ensure that a
10890 * filepath will not refer to parent directories.
10991 */
110- string getAParentDirName ( ) { result = any ( string s | s = ".." or s = "../" ) }
92+ string getAParentDirName ( ) { result = ".." or result = "../" }
11193
11294 /** A check that a path string does not include '..' */
11395 class NoParentDirSanitizerGuard extends SanitizerGuard {
0 commit comments