Skip to content

Commit f102f9f

Browse files
committed
Python: Add models for zstd.compression
See https://docs.python.org/3/library/compression.zstd.html for information about this library. As far as I can tell, the `zstd` library is not vulnerable to things like ZipSlip, but it _could_ be vulnerable to a decompression bomb attack, so I extended those models accordingly.
1 parent fe18e0e commit f102f9f

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

python/ql/src/experimental/semmle/python/security/DecompressionBomb.qll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,46 @@ module Lzma {
364364
}
365365
}
366366

367+
/** Provides sinks and additional taint steps related to the `zstd` library in Python 3.14+. */
368+
module Zstd {
369+
private API::Node zstdInstance() {
370+
result = API::moduleImport("compression").getMember("zstd").getMember(["ZstdFile", "open"])
371+
}
372+
373+
/**
374+
* The Decompression Sinks of `zstd` library
375+
*
376+
* `zstd.open(sink)`
377+
* `zstd.ZstdFile(sink)`
378+
*
379+
* only read mode is sink
380+
*/
381+
class DecompressionSink extends DecompressionBomb::Sink {
382+
DecompressionSink() {
383+
exists(API::CallNode zstdCall | zstdCall = zstdInstance().getACall() |
384+
this = zstdCall.getParameter(0, "filename").asSink() and
385+
(
386+
not exists(
387+
zstdCall
388+
.getParameter(1, "mode")
389+
.getAValueReachingSink()
390+
.asExpr()
391+
.(StringLiteral)
392+
.getText()
393+
) or
394+
zstdCall
395+
.getParameter(1, "mode")
396+
.getAValueReachingSink()
397+
.asExpr()
398+
.(StringLiteral)
399+
.getText()
400+
.matches("%r%")
401+
)
402+
)
403+
}
404+
}
405+
}
406+
367407
/**
368408
* `io.TextIOWrapper(ip, encoding='utf-8')` like following:
369409
* ```python

0 commit comments

Comments
 (0)