@@ -20,7 +20,7 @@ module ZipSlip {
2020 */
2121 abstract class SanitizerGuard extends TaintTracking:: SanitizerGuardNode , DataFlow:: ValueNode { }
2222
23- /** A taint tracking configuration for Zip Slip */
23+ /** A taint tracking configuration for unsafe zip extraction. */
2424 class Configuration extends TaintTracking:: Configuration {
2525 Configuration ( ) { this = "ZipSlip" }
2626
@@ -36,51 +36,54 @@ module ZipSlip {
3636 /**
3737 * Gets a node that can be a parsed zip archive.
3838 */
39- DataFlow:: SourceNode parsedArchive ( ) {
39+ private DataFlow:: SourceNode parsedArchive ( ) {
4040 result = DataFlow:: moduleImport ( "unzip" ) .getAMemberCall ( "Parse" )
4141 or
4242 // `streamProducer.pipe(unzip.Parse())` is a typical (but not
4343 // universal) pattern when using nodejs streams, whose return
4444 // value is the parsed stream.
45- exists ( DataFlow:: MethodCallNode pipe | pipe .getMethodName ( ) = "pipe"
46- and parsedArchive ( ) .flowsTo ( pipe .getArgument ( 0 ) ) )
45+ exists ( DataFlow:: MethodCallNode pipe |
46+ pipe .getMethodName ( ) = "pipe" and
47+ parsedArchive ( ) .flowsTo ( pipe .getArgument ( 0 ) )
48+ )
4749 }
4850
49- /**
50- * An access to the filepath of an entry of a zipfile being extracted
51- * by npm module `unzip`. For example, in
52- * ```javascript
53- * const unzip = require('unzip');
54- *
55- * fs.createReadStream('archive.zip')
56- * .pipe(unzip.Parse())
57- * .on('entry', entry => {
58- * const path = entry.path;
59- * });
60- * ```
61- * there is an `UnzipEntrySource` node corresponding to
62- * the expression `entry.path`.
63- */
51+ /** A zip archive entry path access, as a source for unsafe zip extraction. */
6452 class UnzipEntrySource extends Source {
53+ // For example, in
54+ // ```javascript
55+ // const unzip = require('unzip');
56+ //
57+ // fs.createReadStream('archive.zip')
58+ // .pipe(unzip.Parse())
59+ // .on('entry', entry => {
60+ // const path = entry.path;
61+ // });
62+ // ```
63+ // there is an `UnzipEntrySource` node corresponding to
64+ // the expression `entry.path`.
6565 UnzipEntrySource ( ) {
66- this = parsedArchive ( ) .getAMemberCall ( "on" ) .getCallback ( 1 ) .getParameter ( 0 ) .getAPropertyRead ( "path" )
66+ this = parsedArchive ( )
67+ .getAMemberCall ( "on" )
68+ .getCallback ( 1 )
69+ .getParameter ( 0 )
70+ .getAPropertyRead ( "path" )
6771 }
6872 }
6973
70- /**
71- * A sink that is the path that a createWriteStream gets created at.
72- * This is not covered by FileSystemWriteSink, because it is
73- * required that a write actually takes place to the stream.
74- * However, we want to consider even the bare createWriteStream to
75- * be a zipslip vulnerability since it may truncate an existing file.
76- */
74+ /** A call to `fs.createWriteStream`, as a sink for unsafe zip extraction. */
7775 class CreateWriteStreamSink extends Sink {
7876 CreateWriteStreamSink ( ) {
77+ // This is not covered by `FileSystemWriteSink`, because it is
78+ // required that a write actually takes place to the stream.
79+ // However, we want to consider even the bare createWriteStream
80+ // to be a zipslip vulnerability since it may truncate an
81+ // existing file.
7982 this = DataFlow:: moduleImport ( "fs" ) .getAMemberCall ( "createWriteStream" ) .getArgument ( 0 )
8083 }
8184 }
8285
83- /** A sink that is a file path that gets written to . */
86+ /** A file path of a file write, as a sink for unsafe zip extraction . */
8487 class FileSystemWriteSink extends Sink {
8588 FileSystemWriteSink ( ) { exists ( FileSystemWriteAccess fsw | fsw .getAPathArgument ( ) = this ) }
8689 }
@@ -89,7 +92,7 @@ module ZipSlip {
8992 * Gets a string which suffices to search for to ensure that a
9093 * filepath will not refer to parent directories.
9194 */
92- string getAParentDirName ( ) { result = ".." or result = "../" }
95+ private string getAParentDirName ( ) { result = ".." or result = "../" }
9396
9497 /** A check that a path string does not include '..' */
9598 class NoParentDirSanitizerGuard extends SanitizerGuard {
0 commit comments