Skip to content

Commit edcb3ba

Browse files
committed
add file sources from jszip to js/zip-slip
1 parent eee03eb commit edcb3ba

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added sources from the [`jszip`](https://www.npmjs.com/package/jszip) library to the `js/zipslip` query.

javascript/ql/lib/semmle/javascript/security/dataflow/ZipSlipCustomizations.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ module ZipSlip {
9797
}
9898
}
9999

100+
private import semmle.javascript.DynamicPropertyAccess as DynamicPropertyAccess
101+
102+
/** A object key in the JSZip files object */
103+
class JSZipFilesSource extends Source instanceof DynamicPropertyAccess::EnumeratedPropName {
104+
JSZipFilesSource() {
105+
super.getSourceObject() =
106+
API::moduleImport("jszip").getInstance().getMember("files").getAnImmediateUse()
107+
}
108+
}
109+
110+
/** A relative path from iterating the files in the JSZip object */
111+
class JSZipFileSource extends Source {
112+
JSZipFileSource() {
113+
this =
114+
API::moduleImport("jszip")
115+
.getInstance()
116+
.getMember(["forEach", "filter"])
117+
.getParameter(0)
118+
.getParameter(0)
119+
.getAnImmediateUse()
120+
}
121+
}
122+
100123
/** A call to `fs.createWriteStream`, as a sink for unsafe archive extraction. */
101124
class CreateWriteStreamSink extends Sink {
102125
CreateWriteStreamSink() {

javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ nodes
4545
| ZipSlipBad.js:23:28:23:35 | fileName |
4646
| ZipSlipBad.js:23:28:23:35 | fileName |
4747
| ZipSlipBad.js:23:28:23:35 | fileName |
48+
| ZipSlipBad.js:29:14:29:17 | name |
49+
| ZipSlipBad.js:29:14:29:17 | name |
50+
| ZipSlipBad.js:29:14:29:17 | name |
51+
| ZipSlipBad.js:30:26:30:29 | name |
52+
| ZipSlipBad.js:30:26:30:29 | name |
53+
| ZipSlipBad.js:30:26:30:29 | name |
54+
| ZipSlipBad.js:33:16:33:19 | name |
55+
| ZipSlipBad.js:33:16:33:19 | name |
56+
| ZipSlipBad.js:33:16:33:19 | name |
57+
| ZipSlipBad.js:34:26:34:29 | name |
58+
| ZipSlipBad.js:34:26:34:29 | name |
59+
| ZipSlipBad.js:34:26:34:29 | name |
4860
| ZipSlipBadUnzipper.js:7:9:7:29 | fileName |
4961
| ZipSlipBadUnzipper.js:7:9:7:29 | fileName |
5062
| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path |
@@ -91,6 +103,20 @@ edges
91103
| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName |
92104
| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName |
93105
| ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:22:11:22:31 | fileName |
106+
| ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name |
107+
| ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name |
108+
| ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name |
109+
| ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name |
110+
| ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name |
111+
| ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name |
112+
| ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name |
113+
| ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name |
114+
| ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name |
115+
| ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name |
116+
| ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name |
117+
| ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name |
118+
| ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name |
119+
| ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name |
94120
| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName |
95121
| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName |
96122
| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName |
@@ -107,4 +133,6 @@ edges
107133
| ZipSlipBad.js:8:37:8:44 | fileName | ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:8:37:8:44 | fileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBad.js:7:22:7:31 | entry.path | item path |
108134
| ZipSlipBad.js:16:30:16:37 | fileName | ZipSlipBad.js:15:22:15:31 | entry.path | ZipSlipBad.js:16:30:16:37 | fileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBad.js:15:22:15:31 | entry.path | item path |
109135
| ZipSlipBad.js:23:28:23:35 | fileName | ZipSlipBad.js:22:22:22:31 | entry.path | ZipSlipBad.js:23:28:23:35 | fileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBad.js:22:22:22:31 | entry.path | item path |
136+
| ZipSlipBad.js:30:26:30:29 | name | ZipSlipBad.js:29:14:29:17 | name | ZipSlipBad.js:30:26:30:29 | name | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBad.js:29:14:29:17 | name | item path |
137+
| ZipSlipBad.js:34:26:34:29 | name | ZipSlipBad.js:33:16:33:19 | name | ZipSlipBad.js:34:26:34:29 | name | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBad.js:33:16:33:19 | name | item path |
110138
| ZipSlipBadUnzipper.js:8:37:8:44 | fileName | ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | item path |

javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlipBad.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,16 @@ fs.createReadStream('archive.zip')
2121
.on('entry', entry => {
2222
const fileName = entry.path;
2323
var file = fs.openSync(fileName, "w");
24-
});
24+
});
25+
26+
const JSZip = require('jszip');
27+
const zip = new JSZip();
28+
function doZipSlip() {
29+
for (const name in zip.files) {
30+
fs.createWriteStream(name);
31+
}
32+
33+
zip.forEach((name, file) => {
34+
fs.createWriteStream(name);
35+
});
36+
}

0 commit comments

Comments
 (0)