diff --git a/python/ql/src/experimental/Security/CWE-409/DecompressionBombs.qhelp b/python/ql/src/experimental/Security/CWE-409/DecompressionBombs.qhelp new file mode 100644 index 00000000000..309b4e7b34c --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-409/DecompressionBombs.qhelp @@ -0,0 +1,34 @@ + + + +

Extracting Compressed files with any compression algorithm like gzip can cause to denial of service attacks.

+

Attackers can compress a huge file which created by repeated similiar byte and convert it to a small compressed file.

+ +
+ + +

When you want to decompress a user-provided compressed file you must be careful about the decompression ratio or read these files within a loop byte by byte to be able to manage the decompressed size in each cycle of the loop.

+ +
+ +

python ZipFile library is vulnerable by default

+ + +

By checking the decompressed size from input zipped file you can check the decompression ratio. attackers can forge this decompressed size header too. +So can't rely on file_size attribute of ZipInfo class. this is recommended to use "ZipFile.open" method to be able to manage decompressed size.

+

Reading decompressed file byte by byte and verifying the total current size in each loop cycle in recommended to use in any decompression library.

+ +
+ + +
  • +CVE-2023-22898 +
  • +
  • +A great research to gain more impact by this kind of attack +
  • + +
    +
    diff --git a/python/ql/src/experimental/Security/CWE-409/DecompressionBombs.ql b/python/ql/src/experimental/Security/CWE-409/DecompressionBombs.ql new file mode 100644 index 00000000000..7f8f493decf --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-409/DecompressionBombs.ql @@ -0,0 +1,602 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision medium + * @id py/user-controlled-file-decompression + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import semmle.python.ApiGraphs +import semmle.python.dataflow.new.RemoteFlowSources +import semmle.python.dataflow.new.internal.DataFlowPublic + +module pyZipFile { + /** + * ```python + * zipfile.PyZipFile() + */ + private API::Node pyZipFileClass() { + result = API::moduleImport("zipfile").getMember("PyZipFile") + } + + /** + * same as zipfileSinks + */ + DataFlow::Node isSink() { result = sink(pyZipFileClass()).getACall() } + + private API::Node sink(API::Node pyZipFileClass) { + result = pyZipFileClass.getReturn().getMember(["extractall", "read", "extract", "testzip"]) + or + result = pyZipFileClass.getReturn().getMember("open") and + // only read mode is sink + // mode can be set in open() argument or in PyZipFile instantiation argument + ( + not exists( + result + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + result + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() = "r" + ) and + ( + not exists( + pyZipFileClass + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + pyZipFileClass + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() = "r" + ) + } + + /** + * Same as ZipFile + * I made PyZipFile seperated from ZipFile as in future this will be compatible + * if anyone want to add new methods an sink to each object. + */ + predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(API::Node pyZipFileClass | pyZipFileClass = pyZipFileClass() | + nodeFrom = pyZipFileClass.getACall().getParameter(0, "file").asSink() and + nodeTo = + [ + sink(pyZipFileClass).getACall(), + pyZipFileClass + .getACall() + .getReturn() + .getMember(["extractall", "read", "extract", "testzip"]) + .getACall() + ] + ) + } +} + +module Lzma { + private API::Node lzmaClass() { + result = API::moduleImport("lzma").getMember(["LZMAFile", "open"]) + } + + /** + * `lzma.open(sink)` + * `lzma.LZMAFile(sink)` + * only read mode is sink + */ + DataFlow::Node isSink() { + exists(API::Node lzmaClass | lzmaClass = lzmaClass() | + result = lzmaClass.getACall().getParameter(0, "filename").asSink() and + ( + not exists( + lzmaClass + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + lzmaClass + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + .matches("%r%") + ) + ) + } +} + +module Bz2 { + private API::Node bz2Class() { result = API::moduleImport("bz2").getMember(["BZ2File", "open"]) } + + /** + * `bz2.open(sink)` + * `bz2.BZ2File(sink)` + * only read mode is sink + */ + DataFlow::Node isSink() { + exists(API::Node bz2Class | bz2Class = bz2Class() | + result = bz2Class.getACall().getParameter(0, "filename").asSink() and + ( + not exists( + bz2Class + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + bz2Class + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + .matches("%r%") + ) + ) + } +} + +module Gzip { + private API::Node gzipClass() { + result = API::moduleImport("gzip").getMember(["GzipFile", "open"]) + } + + /** + * `gzip.open(sink)` + * `gzip.GzipFile(sink)` + * only read mode is sink + */ + DataFlow::Node isSink() { + exists(API::Node gzipClass | gzipClass = gzipClass() | + result = gzipClass.getACall().getParameter(0, "filename").asSink() and + ( + not exists( + gzipClass + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + gzipClass + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + .matches("%r%") + ) + ) + } +} + +module ZipFile { + // more sinks file:///home/am/CodeQL-home/codeql-repo/python/ql/src/experimental/semmle/python/security/ZipSlip.qll + /** + * ```python + * zipfile.ZipFile() + * ``` + */ + private API::Node zipFileClass() { result = API::moduleImport("zipfile").getMember("ZipFile") } + + /** + * ```python + * zipfile.ZipFile("zipfileName.zip") + * # read() or one of ["read", "readline", "readlines", "seek", "tell", "__iter__", "__next__"] + * myzip.open('eggs.txt',"r").read() + * # I decided to choice open method with "r" mode as sink + * # because opening zipfile with "r" mode mostly is for reading content of that file + * # so we have a very few of FP here + * next(myzip.open('eggs.txt')) + * myzip.extractall() + * myzip.read() + * myzip.extract() + * # testzip not a RAM consumer but it uses as much CPU as possible + * myzip.testzip() + * + * ``` + */ + private API::Node sink(API::Node zipFileInstance) { + // we can go forward one more step and check whether we call the required methods for read + // or just opening zipfile for reading is enough ( mode = "r") + // result = + // zipfileReturnIOFile() + // .getReturn() + // .getMember(["read", "readline", "readlines", "seek", "tell", "__iter__", "__next__"]) + // or + ( + result = zipFileInstance.getReturn().getMember(["extractall", "read", "extract", "testzip"]) + or + result = zipFileInstance.getReturn().getMember("open") and + ( + not exists( + result + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + result + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() = "r" + ) and + ( + not exists( + zipFileInstance + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + zipFileInstance + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() = "r" + ) and + zipFileSanitizer(result) + ) and + exists(result.getACall().getLocation().getFile().getRelativePath()) + } + + /** + * a sanitizers which check if there is a managed read + * ```python + * with zipfile.ZipFile(zipFileName) as myzip: + * with myzip.open(fileinfo.filename, mode="r") as myfile: + * while chunk: + * chunk = myfile.read(buffer_size) + * total_size += buffer_size + * if total_size > SIZE_THRESHOLD: + * ... + * ``` + */ + predicate zipFileSanitizer(API::Node n) { + not TaintTracking::localExprTaint(n.getReturn() + .getMember("read") + .getParameter(0) + .asSink() + .asExpr(), any(Compare i).getASubExpression*()) + } + + DataFlow::Node isSink() { result = sink(zipFileClass()).getACall() } + + /** + * ```python + * nodeFrom = "zipFileName.zip" + * myZip = zipfile.ZipFile(nodeFrom) + * nodeTo2 = myZip.open('eggs.txt',"r") + * + * nodeTo = myZip.extractall() + * nodeTo = myZip.read() + * nodeTo = myZip.extract() + * # testzip not a RAM consumer but it uses as much CPU as possible + * nodeTo = myZip.testzip() + * + * ``` + */ + predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(API::Node zipFileInstance | zipFileInstance = zipFileClass() | + nodeFrom = zipFileInstance.getACall().getParameter(0, "file").asSink() and + nodeTo = + [ + sink(zipFileInstance).getACall(), + zipFileInstance + .getACall() + .getReturn() + .getMember(["extractall", "read", "extract", "testzip"]) + .getACall() + ] + ) and + exists(nodeTo.getLocation().getFile().getRelativePath()) + } +} + +module TarFile { + /** + * tarfile.open + * + * tarfile.Tarfile.open/xzopen/gzopen/bz2open + * and not mode="r:" which means no compression accepted + */ + API::Node tarfileInstance() { + result = + [ + API::moduleImport("tarfile").getMember("open"), + API::moduleImport("tarfile") + .getMember("TarFile") + .getMember(["xzopen", "gzopen", "bz2open", "open"]) + ] and + ( + not exists( + result + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + ) or + not result + .getACall() + .getParameter(1, "mode") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() + .matches("r:%") + ) + } + + /** + * a Call of + * `tarfile.open(filepath).extractall()/extract()/extractfile()` + * or + * `tarfile.Tarfile.xzopen()/gzopen()/bz2open()` + */ + DataFlow::Node isSink() { + result = + tarfileInstance().getReturn().getMember(["extractall", "extract", "extractfile"]).getACall() + } + + predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(API::Node tarfileInstance | tarfileInstance = tarfileInstance() | + nodeFrom = tarfileInstance.getACall().getParameter(0, "name").asSink() and + nodeTo = + tarfileInstance.getReturn().getMember(["extractall", "extract", "extractfile"]).getACall() + ) + } +} + +module Shutil { + DataFlow::Node isSink() { + result = + [ + API::moduleImport("shutil") + .getMember("unpack_archive") + .getACall() + .getParameter(0, "filename") + .asSink() + ] + } +} + +module Pandas { + DataFlow::Node isSink() { + exists(API::CallNode calltoPandasMethods | + ( + calltoPandasMethods = + API::moduleImport("pandas") + .getMember([ + "read_csv", "read_json", "read_sas", "read_stata", "read_table", "read_xml" + ]) + .getACall() and + result = calltoPandasMethods.getArg(0) + or + calltoPandasMethods = + API::moduleImport("pandas") + .getMember(["read_csv", "read_sas", "read_stata", "read_table"]) + .getACall() and + result = calltoPandasMethods.getArgByName("filepath_or_buffer") + or + calltoPandasMethods = API::moduleImport("pandas").getMember("read_json").getACall() and + result = calltoPandasMethods.getArgByName("path_or_buf") + or + calltoPandasMethods = API::moduleImport("pandas").getMember("read_xml").getACall() and + result = calltoPandasMethods.getArgByName("path_or_buffer") + ) and + ( + not exists(calltoPandasMethods.getArgByName("compression")) + or + not calltoPandasMethods + .getKeywordParameter("compression") + .getAValueReachingSink() + .asExpr() + .(StrConst) + .getText() = "tar" + ) + ) + } +} + +module FileAndFormRemoteFlowSource { + class FastAPI extends DataFlow::Node { + FastAPI() { + exists(API::Node fastAPIParam | + fastAPIParam = + API::moduleImport("fastapi") + .getMember("FastAPI") + .getReturn() + .getMember("post") + .getReturn() + .getParameter(0) + .getKeywordParameter(_) and + API::moduleImport("fastapi") + .getMember("UploadFile") + .getASubclass*() + .getAValueReachableFromSource() + .asExpr() = + fastAPIParam.asSource().asExpr().(Parameter).getAnnotation().getASubExpression*() + | + // in the case of List of files + exists(For f, Attribute attr, DataFlow::Node a, DataFlow::Node b | + fastAPIParam.getAValueReachableFromSource().asExpr() = f.getIter().getASubExpression*() + | + // file.file in following + // def upload(files: List[UploadFile] = File(...)): + // for file in files: + // **file.file** + // thanks Arthur Baars for helping me in following + TaintTracking::localTaint(a, b) and + a.asExpr() = f.getIter() and + b.asExpr() = attr.getObject() and + attr.getName() = ["filename", "content_type", "headers", "file", "read"] and + this.asExpr() = attr + ) + or + // exclude cases like type-annotated with `Response` + // and not not any(Response::RequestHandlerParam src).asExpr() = result + this = + [ + fastAPIParam.asSource(), + fastAPIParam.getMember(["filename", "content_type", "headers", "file"]).asSource(), + fastAPIParam.getMember(["read"]).getReturn().asSource(), + // file-like object, I'm trying to not do additional work here by using already existing file-like objs if it is possible + // fastAPIParam.getMember("file").getAMember().asSource(), + ] + ) + or + exists(API::Node fastAPIParam | + fastAPIParam = + API::moduleImport("fastapi") + .getMember("FastAPI") + .getReturn() + .getMember("post") + .getReturn() + .getParameter(0) + .getKeywordParameter(_) and + API::moduleImport("fastapi") + .getMember("File") + .getASubclass*() + .getAValueReachableFromSource() + .asExpr() = + fastAPIParam.asSource().asExpr().(Parameter).getAnnotation().getASubExpression*() + | + // in the case of List of files + exists(For f, Attribute attr, DataFlow::Node a, DataFlow::Node b | + fastAPIParam.getAValueReachableFromSource().asExpr() = f.getIter().getASubExpression*() + | + // file.file in following + // def upload(files: List[UploadFile] = File(...)): + // for file in files: + // **file.file** + // thanks Arthur Baars for helping me in following + TaintTracking::localTaint(a, b) and + a.asExpr() = f.getIter() and + b.asExpr() = attr.getObject() and + attr.getName() = "file" and + this.asExpr() = attr + ) + or + // exclude cases like type-annotated with `Response` + // and not not any(Response::RequestHandlerParam src).asExpr() = result + this = fastAPIParam.asSource() + ) and + exists(this.getLocation().getFile().getRelativePath()) + } + } +} + +/** + * `io.TextIOWrapper(ip, encoding='utf-8')` like following: + * ```python + * with gzip.open(bomb_input, 'rb') as ip: + * with io.TextIOWrapper(ip, encoding='utf-8') as decoder: + * content = decoder.read() + * print(content) + * ``` + * I saw this builtin method many places so I added it as a AdditionalTaintStep. + * it would be nice if it is added as a global AdditionalTaintStep + */ +predicate isAdditionalTaintStepTextIOWrapper(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(API::CallNode textIOWrapper | + textIOWrapper = API::moduleImport("io").getMember("TextIOWrapper").getACall() + | + nodeFrom = textIOWrapper.getParameter(0, "input").asSink() and + nodeTo = textIOWrapper + ) and + exists(nodeTo.getLocation().getFile().getRelativePath()) +} + +module BombsConfig implements DataFlow::ConfigSig { + // borrowed from UnsafeUnpackQuery.qll + predicate isSource(DataFlow::Node source) { + source instanceof RemoteFlowSource + or + exists(MethodCallNode args | + args = source.(AttrRead).getObject().getALocalSource() and + args = + [ + API::moduleImport("argparse") + .getMember("ArgumentParser") + .getReturn() + .getMember("parse_args") + .getACall(), API::moduleImport("os").getMember("getenv").getACall(), + API::moduleImport("os").getMember("environ").getMember("get").getACall() + ] + ) + or + source instanceof FileAndFormRemoteFlowSource::FastAPI + } + + predicate isSink(DataFlow::Node sink) { + sink = + [ + pyZipFile::isSink(), ZipFile::isSink(), Gzip::isSink(), Lzma::isSink(), Bz2::isSink(), + TarFile::isSink(), Lzma::isSink(), Shutil::isSink(), Pandas::isSink() + ] and + exists(sink.getLocation().getFile().getRelativePath()) + } + + predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + ( + isAdditionalTaintStepTextIOWrapper(nodeFrom, nodeTo) or + ZipFile::isAdditionalTaintStep(nodeFrom, nodeTo) or + pyZipFile::isAdditionalTaintStep(nodeFrom, nodeTo) or + TarFile::isAdditionalTaintStep(nodeFrom, nodeTo) + ) and + exists(nodeTo.getLocation().getFile().getRelativePath()) + } +} + +module Bombs = TaintTracking::Global; + +import Bombs::PathGraph + +from Bombs::PathNode source, Bombs::PathNode sink +where Bombs::flowPath(source, sink) +select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/python/ql/src/experimental/Security/CWE-409/example_bad.py b/python/ql/src/experimental/Security/CWE-409/example_bad.py new file mode 100644 index 00000000000..32442366458 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-409/example_bad.py @@ -0,0 +1,5 @@ +import zipfile + + +def Bad(zip_path): + zipfile.ZipFile(zip_path, "r").extract("filename", "./tmp/") diff --git a/python/ql/src/experimental/Security/CWE-409/example_good.py b/python/ql/src/experimental/Security/CWE-409/example_good.py new file mode 100644 index 00000000000..f11c7bba097 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-409/example_good.py @@ -0,0 +1,21 @@ +import zipfile + + +def safeUnzip(zipFileName): + buffer_size = 2 ** 10 * 8 + total_size = 0 + SIZE_THRESHOLD = 2 ** 10 * 100 + with zipfile.ZipFile(zipFileName) as myzip: + for fileinfo in myzip.infolist(): + content = b'' + with myzip.open(fileinfo.filename, mode="r") as myfile: + chunk = myfile.read(buffer_size) + while chunk: + chunk = myfile.read(buffer_size) + total_size += buffer_size + if total_size > SIZE_THRESHOLD: + print("Bomb detected") + return + content += chunk + print(bytes.decode(content, 'utf-8')) + return "No Bombs!" diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected new file mode 100644 index 00000000000..94839132e56 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected @@ -0,0 +1,258 @@ +edges +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:9:27:9:36 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:11:15:11:24 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:12:19:12:28 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:14:15:14:24 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:15:19:15:28 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:17:20:17:29 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:23:14:23:23 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:24:17:24:26 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:27:40:27:49 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:29:23:29:32 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:30:21:30:30 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:32:40:32:49 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:33:22:33:31 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:34:21:34:30 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:35:42:35:51 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:36:23:36:32 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:37:36:37:45 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:53:10:53:19 | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:53:10:53:19 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | +| file:///usr/lib/python3.10/zipfile.py:344:24:344:31 | ControlFlowNode for filename | file:///usr/lib/python3.10/zipfile.py:351:24:351:44 | ControlFlowNode for Subscript | +| file:///usr/lib/python3.10/zipfile.py:344:24:344:31 | ControlFlowNode for filename | file:///usr/lib/python3.10/zipfile.py:358:25:358:32 | ControlFlowNode for filename | +| file:///usr/lib/python3.10/zipfile.py:351:24:351:44 | ControlFlowNode for Subscript | file:///usr/lib/python3.10/zipfile.py:358:25:358:32 | ControlFlowNode for filename | +| file:///usr/lib/python3.10/zipfile.py:358:25:358:32 | ControlFlowNode for filename | file:///usr/lib/python3.10/zipfile.py:358:9:358:12 | [post] ControlFlowNode for self [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | file:///usr/lib/python3.10/zipfile.py:1258:23:1258:26 | ControlFlowNode for file | +| file:///usr/lib/python3.10/zipfile.py:1258:13:1258:16 | [post] ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1259:13:1259:16 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1258:23:1258:26 | ControlFlowNode for file | file:///usr/lib/python3.10/zipfile.py:1258:13:1258:16 | [post] ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1259:13:1259:16 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1260:9:1260:12 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1260:9:1260:12 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1261:9:1261:12 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1261:9:1261:12 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1262:9:1262:12 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1262:9:1262:12 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1263:9:1263:12 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1263:9:1263:12 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1263:9:1263:12 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1326:26:1326:29 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1326:26:1326:29 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1326:26:1326:29 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1328:14:1328:17 | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1328:14:1328:17 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1328:14:1328:20 | ControlFlowNode for Attribute | +| file:///usr/lib/python3.10/zipfile.py:1328:14:1328:20 | ControlFlowNode for Attribute | file:///usr/lib/python3.10/zipfile.py:1376:25:1376:32 | ControlFlowNode for filename | +| file:///usr/lib/python3.10/zipfile.py:1376:17:1376:33 | ControlFlowNode for ZipInfo() [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1377:13:1377:13 | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1376:25:1376:32 | ControlFlowNode for filename | file:///usr/lib/python3.10/zipfile.py:344:24:344:31 | ControlFlowNode for filename | +| file:///usr/lib/python3.10/zipfile.py:1376:25:1376:32 | ControlFlowNode for filename | file:///usr/lib/python3.10/zipfile.py:1376:17:1376:33 | ControlFlowNode for ZipInfo() [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1377:13:1377:13 | ControlFlowNode for x [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1378:13:1378:13 | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1378:13:1378:13 | ControlFlowNode for x [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1379:13:1379:13 | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1379:13:1379:13 | ControlFlowNode for x [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1388:13:1388:13 | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1388:13:1388:13 | ControlFlowNode for x [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1389:13:1389:13 | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1389:13:1389:13 | ControlFlowNode for x [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1393:13:1393:13 | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1393:13:1393:13 | ControlFlowNode for x [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1394:34:1394:34 | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1394:13:1394:25 | [post] ControlFlowNode for Attribute [List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1394:13:1394:16 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1394:34:1394:34 | ControlFlowNode for x [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1394:13:1394:25 | [post] ControlFlowNode for Attribute [List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1410:18:1410:21 | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1413:16:1413:19 | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1413:16:1413:19 | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1413:16:1413:28 | ControlFlowNode for Attribute [List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1617:23:1617:28 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1628:37:1628:42 | ControlFlowNode for member [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1628:37:1628:42 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1628:16:1628:54 | ControlFlowNode for Attribute() | +| file:///usr/lib/python3.10/zipfile.py:1628:37:1628:42 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1662:31:1662:36 | ControlFlowNode for member [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1662:31:1662:36 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1671:19:1671:24 | ControlFlowNode for member [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1671:19:1671:24 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1671:19:1671:33 | ControlFlowNode for Attribute | +| file:///usr/lib/python3.10/zipfile.py:1671:19:1671:33 | ControlFlowNode for Attribute | file:///usr/lib/python3.10/zipfile.py:1677:19:1677:48 | ControlFlowNode for Subscript | +| file:///usr/lib/python3.10/zipfile.py:1677:19:1677:48 | ControlFlowNode for Subscript | file:///usr/lib/python3.10/zipfile.py:1679:42:1679:42 | SSA variable x | +| file:///usr/lib/python3.10/zipfile.py:1679:36:1680:65 | ControlFlowNode for GeneratorExp | file:///usr/lib/python3.10/zipfile.py:1696:20:1696:29 | ControlFlowNode for targetpath | +| file:///usr/lib/python3.10/zipfile.py:1679:36:1680:65 | ControlFlowNode for GeneratorExp | file:///usr/lib/python3.10/zipfile.py:1702:16:1702:25 | ControlFlowNode for targetpath | +| file:///usr/lib/python3.10/zipfile.py:1679:42:1679:42 | SSA variable x | file:///usr/lib/python3.10/zipfile.py:1679:36:1680:65 | ControlFlowNode for GeneratorExp | +| tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | tarfile_module.py:8:5:8:54 | ControlFlowNode for Attribute() | +| tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | tarfile_module.py:9:5:9:54 | ControlFlowNode for Attribute() | +| tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | tarfile_module.py:10:5:10:56 | ControlFlowNode for Attribute() | +| tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | tarfile_module.py:11:5:11:49 | ControlFlowNode for Attribute() | +| tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | tarfile_module.py:12:5:12:59 | ControlFlowNode for Attribute() | +| tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | tarfile_module.py:13:5:13:51 | ControlFlowNode for Attribute() | +| tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | tarfile_module.py:30:17:30:22 | ControlFlowNode for bar_id | +| tarfile_module.py:30:17:30:22 | ControlFlowNode for bar_id | tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | +| zipfile_module.py:9:17:9:24 | ControlFlowNode for zip_path | zipfile_module.py:11:5:11:57 | ControlFlowNode for Attribute() | +| zipfile_module.py:9:17:9:24 | ControlFlowNode for zip_path | zipfile_module.py:12:34:12:41 | ControlFlowNode for zip_path | +| zipfile_module.py:9:17:9:24 | ControlFlowNode for zip_path | zipfile_module.py:15:5:15:38 | ControlFlowNode for Attribute() | +| zipfile_module.py:9:17:9:24 | ControlFlowNode for zip_path | zipfile_module.py:17:5:17:58 | ControlFlowNode for Attribute() | +| zipfile_module.py:12:18:12:47 | ControlFlowNode for Attribute() [Attribute filelist, List element, Attribute filename] | zipfile_module.py:17:24:17:33 | ControlFlowNode for zipFileObj [Attribute filelist, List element, Attribute filename] | +| zipfile_module.py:12:34:12:41 | ControlFlowNode for zip_path | file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | +| zipfile_module.py:12:34:12:41 | ControlFlowNode for zip_path | zipfile_module.py:12:18:12:47 | ControlFlowNode for Attribute() [Attribute filelist, List element, Attribute filename] | +| zipfile_module.py:17:24:17:33 | ControlFlowNode for zipFileObj [Attribute filelist, List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1410:18:1410:21 | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| zipfile_module.py:17:24:17:33 | ControlFlowNode for zipFileObj [Attribute filelist, List element, Attribute filename] | zipfile_module.py:17:24:17:44 | ControlFlowNode for Attribute() [List element, Attribute filename] | +| zipfile_module.py:17:24:17:44 | ControlFlowNode for Attribute() [List element, Attribute filename] | zipfile_module.py:17:24:17:47 | ControlFlowNode for Subscript [Attribute filename] | +| zipfile_module.py:17:24:17:47 | ControlFlowNode for Subscript [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1617:23:1617:28 | ControlFlowNode for member [Attribute filename] | +| zipfile_module.py:17:24:17:47 | ControlFlowNode for Subscript [Attribute filename] | zipfile_module.py:17:5:17:58 | ControlFlowNode for Attribute() | +| zipfile_module.py:20:20:20:27 | ControlFlowNode for zip_path | zipfile_module.py:30:5:30:35 | ControlFlowNode for Attribute() | +| zipfile_module.py:34:18:34:25 | ControlFlowNode for zip_path | zipfile_module.py:37:14:37:29 | ControlFlowNode for Attribute() | +| zipfile_module.py:34:18:34:25 | ControlFlowNode for zip_path | zipfile_module.py:42:29:42:36 | ControlFlowNode for Attribute | +| zipfile_module.py:34:18:34:25 | ControlFlowNode for zip_path | zipfile_module.py:45:14:45:39 | ControlFlowNode for Attribute() | +| zipfile_module.py:34:18:34:25 | ControlFlowNode for zip_path | zipfile_module.py:53:5:53:35 | ControlFlowNode for Attribute() | +| zipfile_module.py:34:18:34:25 | ControlFlowNode for zip_path | zipfile_module.py:62:44:62:61 | ControlFlowNode for Attribute() | +| zipfile_module.py:42:21:42:37 | ControlFlowNode for BytesIO() | file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | +| zipfile_module.py:42:21:42:37 | ControlFlowNode for BytesIO() | zipfile_module.py:42:5:42:54 | ControlFlowNode for Attribute() | +| zipfile_module.py:42:29:42:36 | ControlFlowNode for Attribute | zipfile_module.py:42:5:42:54 | ControlFlowNode for Attribute() | +| zipfile_module.py:42:29:42:36 | ControlFlowNode for Attribute | zipfile_module.py:42:21:42:37 | ControlFlowNode for BytesIO() | +| zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:90:20:90:25 | ControlFlowNode for bar_id | +| zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:91:17:91:22 | ControlFlowNode for bar_id | +| zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:92:18:92:23 | ControlFlowNode for bar_id | +| zipfile_module.py:90:20:90:25 | ControlFlowNode for bar_id | zipfile_module.py:20:20:20:27 | ControlFlowNode for zip_path | +| zipfile_module.py:91:17:91:22 | ControlFlowNode for bar_id | zipfile_module.py:9:17:9:24 | ControlFlowNode for zip_path | +| zipfile_module.py:92:18:92:23 | ControlFlowNode for bar_id | zipfile_module.py:34:18:34:25 | ControlFlowNode for zip_path | +| zipfile_module.py:99:26:99:34 | ControlFlowNode for Attribute | file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | +| zipfile_module.py:99:26:99:34 | ControlFlowNode for Attribute | zipfile_module.py:100:14:100:29 | ControlFlowNode for Attribute() | +| zipfile_module.py:106:23:106:26 | ControlFlowNode for file | zipfile_module.py:108:14:108:29 | ControlFlowNode for Attribute() | +| zipfile_module.py:116:30:116:38 | ControlFlowNode for Attribute | file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | +| zipfile_module.py:116:30:116:38 | ControlFlowNode for Attribute | zipfile_module.py:117:18:117:33 | ControlFlowNode for Attribute() | +| zipfile_module.py:125:30:125:38 | ControlFlowNode for Attribute | file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | +| zipfile_module.py:125:30:125:38 | ControlFlowNode for Attribute | zipfile_module.py:126:18:126:33 | ControlFlowNode for Attribute() | +nodes +| Other_compresstion_modules.py:7:10:7:19 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:9:27:9:36 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:11:15:11:24 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:12:19:12:28 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:14:15:14:24 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:15:19:15:28 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:17:20:17:29 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:23:14:23:23 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:24:17:24:26 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:27:40:27:49 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:29:23:29:32 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:30:21:30:30 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:32:40:32:49 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:33:22:33:31 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:34:21:34:30 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:35:42:35:51 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:36:23:36:32 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:37:36:37:45 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| Other_compresstion_modules.py:53:10:53:19 | ControlFlowNode for bomb_input | semmle.label | ControlFlowNode for bomb_input | +| file:///usr/lib/python3.10/zipfile.py:344:24:344:31 | ControlFlowNode for filename | semmle.label | ControlFlowNode for filename | +| file:///usr/lib/python3.10/zipfile.py:351:24:351:44 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| file:///usr/lib/python3.10/zipfile.py:358:9:358:12 | [post] ControlFlowNode for self [Attribute filename] | semmle.label | [post] ControlFlowNode for self [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:358:25:358:32 | ControlFlowNode for filename | semmle.label | ControlFlowNode for filename | +| file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | semmle.label | ControlFlowNode for file | +| file:///usr/lib/python3.10/zipfile.py:1258:13:1258:16 | [post] ControlFlowNode for self [Attribute fp] | semmle.label | [post] ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1258:23:1258:26 | ControlFlowNode for file | semmle.label | ControlFlowNode for file | +| file:///usr/lib/python3.10/zipfile.py:1259:13:1259:16 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1260:9:1260:12 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1261:9:1261:12 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1262:9:1262:12 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1263:9:1263:12 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | semmle.label | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | semmle.label | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1326:26:1326:29 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1328:14:1328:17 | ControlFlowNode for self [Attribute fp] | semmle.label | ControlFlowNode for self [Attribute fp] | +| file:///usr/lib/python3.10/zipfile.py:1328:14:1328:20 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| file:///usr/lib/python3.10/zipfile.py:1376:17:1376:33 | ControlFlowNode for ZipInfo() [Attribute filename] | semmle.label | ControlFlowNode for ZipInfo() [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1376:25:1376:32 | ControlFlowNode for filename | semmle.label | ControlFlowNode for filename | +| file:///usr/lib/python3.10/zipfile.py:1377:13:1377:13 | ControlFlowNode for x [Attribute filename] | semmle.label | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1378:13:1378:13 | ControlFlowNode for x [Attribute filename] | semmle.label | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1379:13:1379:13 | ControlFlowNode for x [Attribute filename] | semmle.label | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1388:13:1388:13 | ControlFlowNode for x [Attribute filename] | semmle.label | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1389:13:1389:13 | ControlFlowNode for x [Attribute filename] | semmle.label | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1393:13:1393:13 | ControlFlowNode for x [Attribute filename] | semmle.label | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1394:13:1394:16 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | semmle.label | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1394:13:1394:25 | [post] ControlFlowNode for Attribute [List element, Attribute filename] | semmle.label | [post] ControlFlowNode for Attribute [List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1394:34:1394:34 | ControlFlowNode for x [Attribute filename] | semmle.label | ControlFlowNode for x [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1410:18:1410:21 | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | semmle.label | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1413:16:1413:19 | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | semmle.label | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1413:16:1413:28 | ControlFlowNode for Attribute [List element, Attribute filename] | semmle.label | ControlFlowNode for Attribute [List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1617:23:1617:28 | ControlFlowNode for member [Attribute filename] | semmle.label | ControlFlowNode for member [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1628:16:1628:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| file:///usr/lib/python3.10/zipfile.py:1628:37:1628:42 | ControlFlowNode for member [Attribute filename] | semmle.label | ControlFlowNode for member [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1662:31:1662:36 | ControlFlowNode for member [Attribute filename] | semmle.label | ControlFlowNode for member [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1671:19:1671:24 | ControlFlowNode for member [Attribute filename] | semmle.label | ControlFlowNode for member [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1671:19:1671:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| file:///usr/lib/python3.10/zipfile.py:1677:19:1677:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| file:///usr/lib/python3.10/zipfile.py:1679:36:1680:65 | ControlFlowNode for GeneratorExp | semmle.label | ControlFlowNode for GeneratorExp | +| file:///usr/lib/python3.10/zipfile.py:1679:42:1679:42 | SSA variable x | semmle.label | SSA variable x | +| file:///usr/lib/python3.10/zipfile.py:1696:20:1696:29 | ControlFlowNode for targetpath | semmle.label | ControlFlowNode for targetpath | +| file:///usr/lib/python3.10/zipfile.py:1702:16:1702:25 | ControlFlowNode for targetpath | semmle.label | ControlFlowNode for targetpath | +| tarfile_module.py:5:17:5:24 | ControlFlowNode for tar_path | semmle.label | ControlFlowNode for tar_path | +| tarfile_module.py:8:5:8:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarfile_module.py:9:5:9:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarfile_module.py:10:5:10:56 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarfile_module.py:11:5:11:49 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarfile_module.py:12:5:12:59 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarfile_module.py:13:5:13:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | semmle.label | ControlFlowNode for bar_id | +| tarfile_module.py:30:17:30:22 | ControlFlowNode for bar_id | semmle.label | ControlFlowNode for bar_id | +| zipfile_module.py:9:17:9:24 | ControlFlowNode for zip_path | semmle.label | ControlFlowNode for zip_path | +| zipfile_module.py:11:5:11:57 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:12:18:12:47 | ControlFlowNode for Attribute() [Attribute filelist, List element, Attribute filename] | semmle.label | ControlFlowNode for Attribute() [Attribute filelist, List element, Attribute filename] | +| zipfile_module.py:12:34:12:41 | ControlFlowNode for zip_path | semmle.label | ControlFlowNode for zip_path | +| zipfile_module.py:15:5:15:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:17:5:17:58 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:17:24:17:33 | ControlFlowNode for zipFileObj [Attribute filelist, List element, Attribute filename] | semmle.label | ControlFlowNode for zipFileObj [Attribute filelist, List element, Attribute filename] | +| zipfile_module.py:17:24:17:44 | ControlFlowNode for Attribute() [List element, Attribute filename] | semmle.label | ControlFlowNode for Attribute() [List element, Attribute filename] | +| zipfile_module.py:17:24:17:47 | ControlFlowNode for Subscript [Attribute filename] | semmle.label | ControlFlowNode for Subscript [Attribute filename] | +| zipfile_module.py:20:20:20:27 | ControlFlowNode for zip_path | semmle.label | ControlFlowNode for zip_path | +| zipfile_module.py:30:5:30:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:34:18:34:25 | ControlFlowNode for zip_path | semmle.label | ControlFlowNode for zip_path | +| zipfile_module.py:37:14:37:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:42:5:42:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:42:21:42:37 | ControlFlowNode for BytesIO() | semmle.label | ControlFlowNode for BytesIO() | +| zipfile_module.py:42:29:42:36 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| zipfile_module.py:45:14:45:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:53:5:53:35 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:62:44:62:61 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | semmle.label | ControlFlowNode for bar_id | +| zipfile_module.py:90:20:90:25 | ControlFlowNode for bar_id | semmle.label | ControlFlowNode for bar_id | +| zipfile_module.py:91:17:91:22 | ControlFlowNode for bar_id | semmle.label | ControlFlowNode for bar_id | +| zipfile_module.py:92:18:92:23 | ControlFlowNode for bar_id | semmle.label | ControlFlowNode for bar_id | +| zipfile_module.py:99:26:99:34 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| zipfile_module.py:100:14:100:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:106:23:106:26 | ControlFlowNode for file | semmle.label | ControlFlowNode for file | +| zipfile_module.py:108:14:108:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:116:30:116:38 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| zipfile_module.py:117:18:117:33 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| zipfile_module.py:125:30:125:38 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| zipfile_module.py:126:18:126:33 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +subpaths +| file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1326:26:1326:29 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1394:13:1394:16 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1326:26:1326:29 | ControlFlowNode for self [Attribute fp] | file:///usr/lib/python3.10/zipfile.py:1394:13:1394:16 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1376:25:1376:32 | ControlFlowNode for filename | file:///usr/lib/python3.10/zipfile.py:344:24:344:31 | ControlFlowNode for filename | file:///usr/lib/python3.10/zipfile.py:358:9:358:12 | [post] ControlFlowNode for self [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1376:17:1376:33 | ControlFlowNode for ZipInfo() [Attribute filename] | +| file:///usr/lib/python3.10/zipfile.py:1628:37:1628:42 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1662:31:1662:36 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1696:20:1696:29 | ControlFlowNode for targetpath | file:///usr/lib/python3.10/zipfile.py:1628:16:1628:54 | ControlFlowNode for Attribute() | +| file:///usr/lib/python3.10/zipfile.py:1628:37:1628:42 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1662:31:1662:36 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1702:16:1702:25 | ControlFlowNode for targetpath | file:///usr/lib/python3.10/zipfile.py:1628:16:1628:54 | ControlFlowNode for Attribute() | +| zipfile_module.py:12:34:12:41 | ControlFlowNode for zip_path | file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | file:///usr/lib/python3.10/zipfile.py:1267:17:1267:20 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | zipfile_module.py:12:18:12:47 | ControlFlowNode for Attribute() [Attribute filelist, List element, Attribute filename] | +| zipfile_module.py:12:34:12:41 | ControlFlowNode for zip_path | file:///usr/lib/python3.10/zipfile.py:1216:24:1216:27 | ControlFlowNode for file | file:///usr/lib/python3.10/zipfile.py:1287:21:1287:24 | [post] ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | zipfile_module.py:12:18:12:47 | ControlFlowNode for Attribute() [Attribute filelist, List element, Attribute filename] | +| zipfile_module.py:17:24:17:33 | ControlFlowNode for zipFileObj [Attribute filelist, List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1410:18:1410:21 | ControlFlowNode for self [Attribute filelist, List element, Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1413:16:1413:28 | ControlFlowNode for Attribute [List element, Attribute filename] | zipfile_module.py:17:24:17:44 | ControlFlowNode for Attribute() [List element, Attribute filename] | +| zipfile_module.py:17:24:17:47 | ControlFlowNode for Subscript [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1617:23:1617:28 | ControlFlowNode for member [Attribute filename] | file:///usr/lib/python3.10/zipfile.py:1628:16:1628:54 | ControlFlowNode for Attribute() | zipfile_module.py:17:5:17:58 | ControlFlowNode for Attribute() | +#select +| Other_compresstion_modules.py:9:27:9:36 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:9:27:9:36 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:11:15:11:24 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:11:15:11:24 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:12:19:12:28 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:12:19:12:28 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:14:15:14:24 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:14:15:14:24 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:15:19:15:28 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:15:19:15:28 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:17:20:17:29 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:17:20:17:29 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:23:14:23:23 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:23:14:23:23 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:24:17:24:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:24:17:24:26 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:27:40:27:49 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:27:40:27:49 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:29:23:29:32 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:29:23:29:32 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:30:21:30:30 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:30:21:30:30 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:32:40:32:49 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:32:40:32:49 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:33:22:33:31 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:33:22:33:31 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:34:21:34:30 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:34:21:34:30 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:35:42:35:51 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:35:42:35:51 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:36:23:36:32 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:36:23:36:32 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| Other_compresstion_modules.py:37:36:37:45 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | Other_compresstion_modules.py:37:36:37:45 | ControlFlowNode for bomb_input | This file extraction depends on a $@. | Other_compresstion_modules.py:52:17:52:26 | ControlFlowNode for bomb_input | potentially untrusted source | +| tarfile_module.py:8:5:8:54 | ControlFlowNode for Attribute() | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | tarfile_module.py:8:5:8:54 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | potentially untrusted source | +| tarfile_module.py:9:5:9:54 | ControlFlowNode for Attribute() | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | tarfile_module.py:9:5:9:54 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | potentially untrusted source | +| tarfile_module.py:10:5:10:56 | ControlFlowNode for Attribute() | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | tarfile_module.py:10:5:10:56 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | potentially untrusted source | +| tarfile_module.py:11:5:11:49 | ControlFlowNode for Attribute() | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | tarfile_module.py:11:5:11:49 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | potentially untrusted source | +| tarfile_module.py:12:5:12:59 | ControlFlowNode for Attribute() | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | tarfile_module.py:12:5:12:59 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | potentially untrusted source | +| tarfile_module.py:13:5:13:51 | ControlFlowNode for Attribute() | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | tarfile_module.py:13:5:13:51 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | tarfile_module.py:29:19:29:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:11:5:11:57 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:11:5:11:57 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:15:5:15:38 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:15:5:15:38 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:17:5:17:58 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:17:5:17:58 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:30:5:30:35 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:30:5:30:35 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:37:14:37:29 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:37:14:37:29 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:42:5:42:54 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:42:5:42:54 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:45:14:45:39 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:45:14:45:39 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:53:5:53:35 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:53:5:53:35 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:62:44:62:61 | ControlFlowNode for Attribute() | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | zipfile_module.py:62:44:62:61 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:89:19:89:24 | ControlFlowNode for bar_id | potentially untrusted source | +| zipfile_module.py:100:14:100:29 | ControlFlowNode for Attribute() | zipfile_module.py:99:26:99:34 | ControlFlowNode for Attribute | zipfile_module.py:100:14:100:29 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:99:26:99:34 | ControlFlowNode for Attribute | potentially untrusted source | +| zipfile_module.py:108:14:108:29 | ControlFlowNode for Attribute() | zipfile_module.py:106:23:106:26 | ControlFlowNode for file | zipfile_module.py:108:14:108:29 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:106:23:106:26 | ControlFlowNode for file | potentially untrusted source | +| zipfile_module.py:117:18:117:33 | ControlFlowNode for Attribute() | zipfile_module.py:116:30:116:38 | ControlFlowNode for Attribute | zipfile_module.py:117:18:117:33 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:116:30:116:38 | ControlFlowNode for Attribute | potentially untrusted source | +| zipfile_module.py:126:18:126:33 | ControlFlowNode for Attribute() | zipfile_module.py:125:30:125:38 | ControlFlowNode for Attribute | zipfile_module.py:126:18:126:33 | ControlFlowNode for Attribute() | This file extraction depends on a $@. | zipfile_module.py:125:30:125:38 | ControlFlowNode for Attribute | potentially untrusted source | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.qlref b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.qlref new file mode 100644 index 00000000000..5d425772f9a --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-409/DecompressionBombs.ql \ No newline at end of file diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/Other_compresstion_modules.py b/python/ql/test/experimental/query-tests/Security/CWE-409/Other_compresstion_modules.py new file mode 100644 index 00000000000..0c5e51d24ca --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/Other_compresstion_modules.py @@ -0,0 +1,54 @@ +import io +from fastapi import FastAPI + +app = FastAPI() + + +def bomb(bomb_input): + import shutil + shutil.unpack_archive(bomb_input) + import lzma + lzma.open(bomb_input) + lzma.LZMAFile(bomb_input).read() + import gzip + gzip.open(bomb_input) + gzip.GzipFile(bomb_input).read() + + with gzip.open(bomb_input, 'rb') as ip: + with io.TextIOWrapper(ip, encoding='utf-8') as decoder: + content = decoder.read() + print(content) + + import bz2 + bz2.open(bomb_input) + bz2.BZ2File(bomb_input).read() + + import pandas + pandas.read_csv(filepath_or_buffer=bomb_input) + + pandas.read_table(bomb_input, compression='gzip') + pandas.read_xml(bomb_input, compression='gzip') + + pandas.read_csv(filepath_or_buffer=bomb_input, compression='gzip') + pandas.read_json(bomb_input, compression='gzip') + pandas.read_sas(bomb_input, compression='gzip') + pandas.read_stata(filepath_or_buffer=bomb_input, compression='gzip') + pandas.read_table(bomb_input, compression='gzip') + pandas.read_xml(path_or_buffer=bomb_input, compression='gzip') + + # no compression no DOS + pandas.read_table(bomb_input, compression='tar') + pandas.read_xml(bomb_input, compression='tar') + + pandas.read_csv(filepath_or_buffer=bomb_input, compression='tar') + pandas.read_json(bomb_input, compression='tar') + pandas.read_sas(bomb_input, compression='tar') + pandas.read_stata(filepath_or_buffer=bomb_input, compression='tar') + pandas.read_table(bomb_input, compression='tar') + pandas.read_xml(path_or_buffer=bomb_input, compression='tar') + + +@app.post("/bomb") +async def bombs(bomb_input): + bomb(bomb_input) + return {"message": "non-async"} diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/tarfile_module.py b/python/ql/test/experimental/query-tests/Security/CWE-409/tarfile_module.py new file mode 100644 index 00000000000..cecfb8ee4d3 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/tarfile_module.py @@ -0,0 +1,31 @@ +import tarfile +from fastapi import FastAPI + + +def tar_extract(tar_path): + tarfile.open(tar_path) + tarfile.open(tar_path) + tarfile.TarFile.open(tar_path).extract("somefile") + tarfile.TarFile.open(tar_path).extract("somefile") + tarfile.TarFile.xzopen(tar_path).extract("somefile") + tarfile.TarFile.gzopen(tar_path).extractall() + tarfile.TarFile.open(tar_path).extractfile("file1.txt") + tarfile.open(tar_path).extractfile("file1.txt") + # not working + tarInstance2 = tarfile.TarFile(tar_path) + tarInstance2.extractfile("file1.txt") + tarInstance2.extract("file1.txt") + tarfile.TarFile().open(tar_path) + # good + tarfile.open(tar_path, mode="w") + tarfile.TarFile.gzopen(tar_path, mode="w") + tarfile.TarFile.open(tar_path, mode="r:") + + +app = FastAPI() + + +@app.post("/zipbomb") +async def zipbomb(bar_id): + tar_extract(bar_id) + return {"message": "non-async"} diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/zipfile_module.py b/python/ql/test/experimental/query-tests/Security/CWE-409/zipfile_module.py new file mode 100644 index 00000000000..ef235ba82fb --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/zipfile_module.py @@ -0,0 +1,128 @@ +import zipfile +from io import BytesIO +from urllib import request +import requests +from fastapi import FastAPI, File, UploadFile +from typing import List, Annotated + + +def zip_extract(zip_path): + # we can have PyZipFile instead of ZipFile too + zipfile.ZipFile(zip_path, "r").extract("0", "./tmp/") + zipFileObj = zipfile.ZipFile(zip_path, "r") + zipFileObj2 = zipFileObj + # zipfile.ZipFile("user_input").extract(member="file_name") Consume a lot of CPU,Storage + zipFileObj2.extract("0", "./tmp/") + # zipfile.ZipFile("user_input").extract(member=ZipInfo_object) Consume a lot of CPU,Storage + zipFileObj.extract(zipFileObj.infolist()[0], "./tmp/") + + +def zip_extractall(zip_path): + import httpx + filex = httpx.get(zip_path).read() + zipfile.ZipFile(BytesIO(filex), "r").extractall() + zipFileObj = zipfile.ZipFile(zip_path, "r") + for infolist in zipFileObj.infolist(): + Decompression_ratio = infolist.file_size / infolist.compress_size + if Decompression_ratio > 10: + return + # zipfile.ZipFile("user_input").extractall() Consume a lot of CPU,Storage + zipFileObj.extractall("./tmp/") # Sensitive + zipFileObj.close() + + +def zip_read_obj(zip_path): + # zipfile.ZipFile("user_input").open("file_name").read() Consume a lot of CPU,RAM,Storage + with zipfile.ZipFile(zip_path) as myzip: + with myzip.open('ZZ') as myfile: + a = myfile.readline() + + file = requests.get(zip_path) + zipfile.ZipFile(BytesIO(file.raw), "w").open("aa") + zipfile.ZipFile(BytesIO(file.raw), "r").open("aa") + + with zipfile.ZipFile(zip_path) as myzip: + with myzip.open('ZZ', mode="r") as myfile: + a = next(myfile) + + with zipfile.ZipFile(zip_path) as myzip: + with myzip.open('ZZ', mode="w") as myfile: + a = myfile.write(b"tmpppp") + + myzip = zipfile.PyZipFile(zip_path) + myzip.read(myzip.infolist()[0]) + + zipfile.ZipFile(BytesIO(request.urlopen(zip_path).read()) + ).read("aFileNameInTheZipFile") + + with zipfile.ZipFile(zip_path, 'w') as dst_zip: + with zipfile.ZipFile(zip_path) as src_zip: + for info in src_zip.infolist(): + if info.filename.startswith('classes'): + dst_zip.writestr(info, src_zip.read(info)) + + +def safeUnzip(zipFileName): + buffer_size = 2 ** 10 * 8 + total_size = 0 + SIZE_THRESHOLD = 2 ** 10 * 100 + with zipfile.ZipFile(zipFileName) as myzip: + for fileinfo in myzip.infolist(): + content = b'' + with myzip.open(fileinfo.filename, mode="r") as myfile: + chunk = myfile.read(buffer_size) + while chunk: + chunk = myfile.read(buffer_size) + total_size += buffer_size + if total_size > SIZE_THRESHOLD: + print("Bomb detected") + return + content += chunk + print(bytes.decode(content, 'utf-8')) + return "No Bombs!" + + +app = FastAPI() + + +@app.post("/zipbomb") +async def zipbomb(bar_id): + zip_extractall(bar_id) + zip_extract(bar_id) + zip_read_obj(bar_id) + safeUnzip(bar_id) + return {"message": "non-async"} + + +@app.post("/zipbomb2") +async def zipbomb2(file: UploadFile): + with zipfile.ZipFile(file.file) as myzip: + with myzip.open('ZZ') as myfile: + a = myfile.readline() + return {"message": "non-async"} + + +@app.post("/zipbomb2") +async def create_file(file: Annotated[bytes | None, File()] = None): + with zipfile.ZipFile(file) as myzip: + with myzip.open('ZZ') as myfile: + a = myfile.readline() + return {"message": "non-async"} + + +@app.post("/uploadMultipleFiles") +def upload(files: List[UploadFile] = File(...)): + for file in files: + with zipfile.ZipFile(file.file) as myzip: + with myzip.open('ZZ') as myfile: + a = myfile.readline() + return {"message": "non-async"} + + +@app.post("/files/") +async def create_files(files: Annotated[list[bytes], File()]): + for file in files: + with zipfile.ZipFile(file.file) as myzip: + with myzip.open('ZZ') as myfile: + a = myfile.readline() + return {"file_sizes": [len(file) for file in files]} diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.qlref b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.qlref deleted file mode 100644 index 8bb2c1e9b52..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-522/LDAPInsecureAuth.ql \ No newline at end of file