JavaScript: Add tar-stream extraction to ZipSlip query.

This commit is contained in:
Jason Reed
2019-03-14 13:36:53 -04:00
parent 5a3cf2c5bb
commit 6589813ec7
3 changed files with 28 additions and 6 deletions

View File

@@ -46,6 +46,8 @@ module ZipSlip {
private DataFlow::SourceNode parsedArchive() {
result = DataFlow::moduleImport("unzip").getAMemberCall("Parse")
or
result = DataFlow::moduleImport("tar-stream").getAMemberCall("extract")
or
// `streamProducer.pipe(unzip.Parse())` is a typical (but not
// universal) pattern when using nodejs streams, whose return
// value is the parsed stream.
@@ -56,6 +58,9 @@ module ZipSlip {
)
}
/** Gets a property that is used to get the filename part of an archive entry. */
private string getAFilenameProperty() { result = "path" or result = "name" }
/** A zip archive entry path access, as a source for unsafe zip extraction. */
class UnzipEntrySource extends Source {
// For example, in
@@ -74,9 +79,8 @@ module ZipSlip {
exists(DataFlow::CallNode cn |
cn = parsedArchive().getAMemberCall("on") and
cn.getArgument(0).mayHaveStringValue("entry") and
this = cn.getCallback(1)
.getParameter(0)
.getAPropertyRead("path"))
this = cn.getCallback(1).getParameter(0).getAPropertyRead(getAFilenameProperty())
)
}
}
@@ -99,9 +103,7 @@ module ZipSlip {
/** An expression that sanitizes by calling path.basename */
class BasenameSanitizer extends Sanitizer {
BasenameSanitizer() {
this = DataFlow::moduleImport("path").getAMemberCall("basename")
}
BasenameSanitizer() { this = DataFlow::moduleImport("path").getAMemberCall("basename") }
}
/**