File tree Expand file tree Collapse file tree 2 files changed +33
-3
lines changed
lib/semmle/javascript/security/dataflow
test/query-tests/Security/CWE-022/ZipSlip Expand file tree Collapse file tree 2 files changed +33
-3
lines changed Original file line number Diff line number Diff line change @@ -513,13 +513,24 @@ module TaintedPath {
513
513
514
514
override predicate blocks ( boolean outcome , Expr e ) {
515
515
member = "relative" and
516
- e = pathCall .getArgument ( 1 ) .asExpr ( ) and
516
+ e = maybeGetJoinArg ( pathCall .getArgument ( 1 ) ) .asExpr ( ) and
517
517
outcome = startsWith .getPolarity ( ) .booleanNot ( )
518
518
or
519
519
not member = "relative" and
520
- e = pathCall .getArgument ( 0 ) .asExpr ( ) and
520
+ e = maybeGetJoinArg ( pathCall .getArgument ( 0 ) ) .asExpr ( ) and
521
521
outcome = startsWith .getPolarity ( )
522
522
}
523
+
524
+ bindingset [ e]
525
+ private DataFlow:: Node maybeGetJoinArg ( DataFlow:: Node e ) {
526
+ exists ( DataFlow:: CallNode call |
527
+ call = NodeJSLib:: Path:: moduleMember ( "join" ) .getACall ( ) and e = call
528
+ |
529
+ result = call .getLastArgument ( )
530
+ )
531
+ or
532
+ result = e
533
+ }
523
534
}
524
535
525
536
/**
Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ fs.createReadStream('archive.zip')
25
25
26
26
const JSZip = require ( 'jszip' ) ;
27
27
const zip = new JSZip ( ) ;
28
+ const path = require ( 'path' ) ;
28
29
function doZipSlip ( ) {
29
30
for ( const name in zip . files ) {
30
31
fs . createWriteStream ( name ) ;
@@ -33,4 +34,22 @@ function doZipSlip() {
33
34
zip . forEach ( ( name , file ) => {
34
35
fs . createWriteStream ( name ) ;
35
36
} ) ;
36
- }
37
+
38
+ const extractTo = path . resolve ( "/some/path/to/extract/to" ) ;
39
+ var files = [ ] ;
40
+
41
+ for ( var name in zip . files ) {
42
+ var entry = zip . files [ name ] ;
43
+
44
+ var targetPath = path . resolve (
45
+ path . join ( extractTo , name )
46
+ ) ;
47
+ if ( ! targetPath . startsWith ( extractTo ) ) {
48
+ throw new Error ( "Entry is outside the extraction path" ) ;
49
+ }
50
+ files . push ( name ) ;
51
+ }
52
+ for ( const file of files ) {
53
+ fs . createWriteStream ( path . join ( extractTo , file ) ) ; // OK
54
+ }
55
+ }
You can’t perform that action at this time.
0 commit comments