From d6fa745279e2ef1389697e20fdf9526f5a0c186b Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Wed, 19 Oct 2022 14:01:40 +0100 Subject: [PATCH 01/10] Add TarSlip Improv query --- .../Security/CWE-022bis/TarSlip.qhelp | 60 ++++++++++ .../Security/CWE-022bis/TarSlipImprov.ql | 108 ++++++++++++++++++ .../CWE-022bis/examples/NoHIT_TarSlip_1.py | 19 +++ .../CWE-022bis/examples/NoHIT_TarSlip_2.py | 27 +++++ .../CWE-022bis/examples/NoHIT_TarSlip_3.py | 8 ++ .../CWE-022bis/examples/NoHIT_TarSlip_4.py | 13 +++ .../CWE-022bis/examples/NoHIT_TarSlip_5.py | 29 +++++ .../CWE-022bis/examples/NoHIT_TarSlip_6.py | 26 +++++ .../CWE-022bis/examples/NoHIT_TarSlip_7.py | 29 +++++ .../Security/CWE-022bis/examples/TarSlip_1.py | 18 +++ .../CWE-022bis/examples/TarSlip_10.py | 6 + .../CWE-022bis/examples/TarSlip_11.py | 26 +++++ .../CWE-022bis/examples/TarSlip_12.py | 5 + .../CWE-022bis/examples/TarSlip_13.py | 26 +++++ .../CWE-022bis/examples/TarSlip_14.py | 19 +++ .../CWE-022bis/examples/TarSlip_15.py | 26 +++++ .../CWE-022bis/examples/TarSlip_16.py | 8 ++ .../CWE-022bis/examples/TarSlip_17.py | 8 ++ .../CWE-022bis/examples/TarSlip_18.py | 8 ++ .../CWE-022bis/examples/TarSlip_19.py | 8 ++ .../Security/CWE-022bis/examples/TarSlip_2.py | 10 ++ .../CWE-022bis/examples/TarSlip_20.py | 9 ++ .../CWE-022bis/examples/TarSlip_21.py | 5 + .../CWE-022bis/examples/TarSlip_22.py | 13 +++ .../CWE-022bis/examples/TarSlip_23.py | 6 + .../CWE-022bis/examples/TarSlip_24.py | 26 +++++ .../CWE-022bis/examples/TarSlip_25.py | 5 + .../CWE-022bis/examples/TarSlip_26.py | 20 ++++ .../CWE-022bis/examples/TarSlip_27.py | 8 ++ .../Security/CWE-022bis/examples/TarSlip_3.py | 6 + .../Security/CWE-022bis/examples/TarSlip_4.py | 6 + .../Security/CWE-022bis/examples/TarSlip_5.py | 10 ++ .../Security/CWE-022bis/examples/TarSlip_6.py | 36 ++++++ .../Security/CWE-022bis/examples/TarSlip_7.py | 7 ++ .../Security/CWE-022bis/examples/TarSlip_8.py | 7 ++ .../Security/CWE-022bis/examples/TarSlip_9.py | 6 + .../CWE-022bis/examples/archive_malign.tar | Bin 0 -> 10240 bytes .../Security/CWE-022bis/examples/script.sh | 15 +++ 38 files changed, 672 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-022bis/TarSlip.qhelp create mode 100755 python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py create mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py create mode 100644 python/ql/src/experimental/Security/CWE-022bis/examples/archive_malign.tar create mode 100644 python/ql/src/experimental/Security/CWE-022bis/examples/script.sh diff --git a/python/ql/src/experimental/Security/CWE-022bis/TarSlip.qhelp b/python/ql/src/experimental/Security/CWE-022bis/TarSlip.qhelp new file mode 100644 index 000000000000..75ba15abf429 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/TarSlip.qhelp @@ -0,0 +1,60 @@ + + + + +

Extracting files from a malicious tarball without validating that the destination file path +is within the destination directory can cause files outside the destination directory to be +overwritten, due to the possible presence of directory traversal elements (..) in +archive path names.

+ +

Tarball contain archive entries representing each file in the archive. These entries +include a file path for the entry, but these file paths are not restricted and may contain +unexpected special elements such as the directory traversal element (..). If these +file paths are used to determine an output file to write the contents of the archive item to, then +the file may be written to an unexpected location. This can result in sensitive information being +revealed or deleted, or an attacker being able to influence behavior by modifying unexpected +files.

+ +

For example, if a tarball contains a file entry ../sneaky-file, and the tarball +is extracted to the directory /tmp/tmp123, then naively combining the paths would result +in an output file path of /tmp/tmp123/../sneaky-file, which would cause the file to be +written to /tmp/.

+ +
+ + +

Ensure that output paths constructed from tarball entries are validated +to prevent writing files to unexpected locations.

+ +

The recommended way of writing an output file from a tarball entry is to call extract() or extractall(). +

+ +
+ + +

+In this example an archive is extracted without validating file paths. +

+ + + +

To fix this vulnerability, we need to call the function extractall(). +

+ + + +
+ +
  • +Snyk: +Zip Slip Vulnerability. +
  • + +
  • + Tarfile documentation + extractall() warning +
  • +
    +
    diff --git a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql new file mode 100755 index 000000000000..4871c21ee2c0 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql @@ -0,0 +1,108 @@ +/** + * @name Arbitrary file write during tarfile extraction + * @description Extracting files from a malicious tar archive without validating that the + * destination file path is within the destination directory can cause files outside + * the destination directory to be overwritten. + * @kind path-problem + * @id py/tarslip + * @problem.severity error + * @security-severity 7.5 + * @precision high + * @tags security + * external/cwe/cwe-022 + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import DataFlow::PathGraph +import semmle.python.ApiGraphs +import semmle.python.dataflow.new.internal.Attributes +import semmle.python.dataflow.new.BarrierGuards +import semmle.python.dataflow.new.RemoteFlowSources + +/** + * Handle those three cases of Tarfile opens: + * - `tarfile.open()` + * - `tarfile.TarFile()` + * - `MKtarfile.Tarfile.open()` + */ +API::Node tarfileOpen() { + result in [ + API::moduleImport("tarfile").getMember(["open", "TarFile"]), + API::moduleImport("tarfile").getMember("TarFile").getASubclass().getMember("open") + ] +} + +/** + * Handle the previous three cases, plus the use of `closing` in the previous cases + */ +class AllTarfileOpens extends API::CallNode { + AllTarfileOpens() { + this = tarfileOpen().getACall() + or + exists(API::Node closing, Node arg | + closing = API::moduleImport("contextlib").getMember("closing") and + this = closing.getACall() and + arg = this.getArg(0) and + arg = tarfileOpen().getACall() + ) + } +} +/** + * A taint-tracking configuration for detecting more "TarSlip" vulnerabilities. + */ +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "TarSlip" } + + override predicate isSource(DataFlow::Node source) { source instanceof AllTarfileOpens } + + override predicate isSink(DataFlow::Node sink) { + // A sink capturing method calls to `extractall` without `members` argument. + // For a call to `file.extractall` without `members` argument, `file` is considered a sink. + exists(MethodCallNode call , AllTarfileOpens atfo| + call = atfo.getReturn().getMember("extractall").getACall() and + not exists(Node arg | arg = call.getArgByName("members")) and + sink = call.getObject() + ) + or + // A sink capturing method calls to `extractall` with `members` argument. + // For a call to `file.extractall` with `members` argument, `file` is considered a sink if not + // a the `members` argument contains a NameConstant as None, a List or call to the method `getmembers`. + // Otherwise, the argument of `members` is considered a sink. + exists(MethodCallNode call, Node arg, AllTarfileOpens atfo| + call = atfo.getReturn().getMember("extractall").getACall() and + arg = call.getArgByName("members") and + if + arg.asCfgNode() instanceof NameConstantNode or + arg.asCfgNode() instanceof ListNode + then sink = call.getObject() + else + if arg.(MethodCallNode).getMethodName() = "getmembers" + then sink = arg.(MethodCallNode).getObject() + else sink = call.getArgByName("members") + ) + or + // An argument to `extract` is considered a sink. + exists(AllTarfileOpens atfo | sink = atfo.getReturn().getMember("extract").getACall().getArg(0)) + or + //An argument to `_extract_member` is considered a sink. + exists(MethodCallNode call, AllTarfileOpens atfo | + call = atfo.getReturn().getMember("_extract_member").getACall() and + call.getArg(1).(AttrRead).accesses(sink, "name") + ) + } + + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(AttrRead attr, MethodCallNode call | + attr.accesses(nodeFrom, "getmembers") and + nodeFrom = call.getObject() and + nodeTo = call + ) + } +} + +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink, source, sink, "Extraction of tarfile from $@ to a potentially untrusted source $@.", + source.getNode(), source.getNode().toString(), sink.getNode(), sink.getNode().toString() diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py new file mode 100755 index 000000000000..660ff37bd662 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py @@ -0,0 +1,19 @@ +import sys +import tarfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + result = [] + for member in tar: + if ".." in member.name: + raise ValueError("Path in member name !!!") + result.append(member) + path = sys.argv[2] + #print("files are extracted to: ", path) + tar.extractall(path=path, members=result) + tar.close() + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py new file mode 100755 index 000000000000..afeb9ac26bd7 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py @@ -0,0 +1,27 @@ +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile: + if '../' in member.name: + print('Member name container directory traversal sequence') + continue + elif member.issym() or member.islnk(): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py new file mode 100755 index 000000000000..6911f7bf6298 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py @@ -0,0 +1,8 @@ +import tarfile +import sys + +with tarfile.open(sys.argv[1]) as tar: + for entry in tar: + if ".." in entry.name: + raise ValueError("Illegal tar archive entry") + tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py new file mode 100755 index 000000000000..03f769daf8ab --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py @@ -0,0 +1,13 @@ +import tarfile +import sys +import os + +def _validate_archive_name(name, target): + if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): + raise ValueError(f"Provided language pack contains invalid name {name}") + +with tarfile.open(sys.argv[1]) as tar: + target = "/tmp/unpack" + for entry in tar: + _validate_archive_name(entry.name, target) + tar.extract(entry, target) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py new file mode 100755 index 000000000000..16997f350eee --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py @@ -0,0 +1,29 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile.getmembers(): + if '../' in member.name: + print('Member name container directory traversal sequence') + continue + elif (member.issym() or member.islnk()) and ('../' in member.linkname): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py new file mode 100755 index 000000000000..3301dc4e35c2 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py @@ -0,0 +1,26 @@ +# https://github.com/OctoPrint/OctoPrint/ + +import sys +import tarfile +import os + +def _validate_tar_info(info, target): + _validate_archive_name(info.name, target) + if not (info.isfile() or info.isdir()): + raise ValueError("Provided language pack contains invalid file type") + +def _validate_archive_name(name, target): + if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): + raise ValueError(f"Provided language pack contains invalid name {name}") + +target = "/tmp/unpack" + +with tarfile.open(sys.argv[1], "r") as tar: + + # sanity check + for info in tar.getmembers(): + _validate_tar_info(info, target) + + # unpack everything + tar.extractall(target) + diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py new file mode 100755 index 000000000000..b62fa3e84291 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py @@ -0,0 +1,29 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile.getmembers(): + if '../' in member.name: + print('Member name container directory traversal sequence') + continue + elif member.issym() or member.islnk(): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py new file mode 100755 index 000000000000..212baf4877c8 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py @@ -0,0 +1,18 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tarf = tar.getmembers() + for f in tarf: + if not f.issym(): + tar.extractall(path=tempfile.mkdtemp(), members=[f]) + tar.close() + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py new file mode 100755 index 000000000000..08cf77ad6ce8 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py @@ -0,0 +1,6 @@ +import tarfile +import sys + +tarball = sys.argv[1] +with tarfile.open(tarball, "r") as tar: + tar.extractall(path="/tmp/unpack/", members=tar) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py new file mode 100755 index 000000000000..d007fb2bba50 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py @@ -0,0 +1,26 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile.getmembers(): + if member.issym() or member.islnk(): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py new file mode 100755 index 000000000000..6633ff013712 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py @@ -0,0 +1,5 @@ +import tarfile +import sys + +with tarfile.open(sys.argv[1], "r") as tar: + tar.extractall(path="/tmp/unpack") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py new file mode 100755 index 000000000000..bd0c741e50e3 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py @@ -0,0 +1,26 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile.getmembers(): + if member.issym(): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py new file mode 100755 index 000000000000..91b9c710c5ef --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py @@ -0,0 +1,19 @@ +# https://github.com/tensorflow/tensor2tensor +import tarfile +import os.path +import sys + +# provie the malign archive +filename = sys.argv[1] +tmp_dir = "/tmp/" + +read_type = "r:gz" if filename.endswith("tgz") else "r" +with tarfile.open(filename, read_type) as corpus_tar: + # Create a subset of files that don't already exist. + # tarfile.extractall errors when encountering an existing file + # and tarfile.extract is extremely slow + members = [] + for f in corpus_tar: + if not os.path.isfile(os.path.join(tmp_dir, f.name)): + members.append(f) + corpus_tar.extractall(tmp_dir, members=members) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py new file mode 100755 index 000000000000..675540041b8a --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py @@ -0,0 +1,26 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile.getmembers(): + if not member.isreg(): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py new file mode 100755 index 000000000000..27eb760909ad --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py @@ -0,0 +1,8 @@ +from fileinput import filename +import tarfile +import os.path +import sys + +archive_path = sys.argv[1] +target_dir = "/tmp/unpack" +tarfile.open(archive_path, "r").extractall(path=target_dir) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py new file mode 100755 index 000000000000..0508668e98ed --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py @@ -0,0 +1,8 @@ +import tarfile +import sys + +tarball = sys.argv[1] +with tarfile.open(tarball) as tar: + for entry in tar: + if entry.isfile(): + tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py new file mode 100755 index 000000000000..77d1fc2b2b82 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py @@ -0,0 +1,8 @@ +import tarfile +import sys + +with tarfile.open(sys.argv[1]) as tar: + for entry in tar: + if entry.name.startswith("/"): + raise ValueError("Illegal tar archive entry") + tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py new file mode 100755 index 000000000000..429be70d0210 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py @@ -0,0 +1,8 @@ +import tarfile +import sys + +tarball = sys.argv[1] +with tarfile.TarFile(tarball, mode="r") as tar: + for entry in tar: + if entry.isfile(): + tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py new file mode 100755 index 000000000000..1e7717012e3d --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py @@ -0,0 +1,10 @@ +from tarfile import TarFile +import sys + +class MKTar(TarFile): + pass + +tarball = sys.argv[1] +with MKTar.open(name=tarball) as tar: + for entry in tar: + tar._extract_member(entry, entry.name) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py new file mode 100755 index 000000000000..b8e8542abda0 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py @@ -0,0 +1,9 @@ +import tarfile +import sys +import os + +with tarfile.open(sys.argv[1]) as tar: + for entry in tar: + if os.path.isabs(entry.name): + raise ValueError("Illegal tar archive entry") + tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py new file mode 100755 index 000000000000..4024744ad9af --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py @@ -0,0 +1,5 @@ +import tarfile +import sys + +with tarfile.TarFile(sys.argv[1], mode="r") as tar: + tar.extractall(path="/tmp/unpack") \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py new file mode 100755 index 000000000000..1e9cbd1ed5a0 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py @@ -0,0 +1,13 @@ +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=tar.getmembers()) + tar.close() + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py new file mode 100755 index 000000000000..c433ad6d96e2 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py @@ -0,0 +1,6 @@ +import tarfile +import sys +import tempfile + +tar = tarfile.open(sys.argv[1]) +tar.extractall(path=tempfile.mkdtemp(), members=None) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py new file mode 100755 index 000000000000..13e5771caebb --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py @@ -0,0 +1,26 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) + tar.close() + + +def members_filter(tarfile): + result = [] + for member in tarfile: + if member.issym() or member.islnk(): + print('Symlink to external resource') + continue + result.append(member) + return result + + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py new file mode 100755 index 000000000000..8c21d3a2f0b1 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py @@ -0,0 +1,5 @@ +import tarfile +import sys + +with tarfile.TarFile(sys.argv[1], mode="r") as tar: + tar.extractall(path="/tmp/unpack/", members=tar) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py new file mode 100755 index 000000000000..911c8906e734 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py @@ -0,0 +1,20 @@ +# https://github.com/PyCQA/bandit + +import sys +import tarfile +import tempfile + +def managed_members_archive_handler(filename): + tar = tarfile.open(filename) + result = [] + for member in tar: + if member.issym(): + raise ValueError("But it is a symlink") + result.append(member) + tar.extractall(path=tempfile.mkdtemp(), members=result) + tar.close() + +if __name__ == "__main__": + if len(sys.argv) > 1: + filename = sys.argv[1] + managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py new file mode 100755 index 000000000000..a6434d87f3d3 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py @@ -0,0 +1,8 @@ +from fileinput import filename +import tarfile +import os.path +import sys + +archive_path = sys.argv[1] +target_dir = "/tmp/unpack" +tarfile.TarFile(sys.argv[1], mode="r").extractall(path=target_dir) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py new file mode 100755 index 000000000000..2e56a0bf88a7 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py @@ -0,0 +1,6 @@ +import tarfile +import sys + +tarball = sys.argv[1] +with tarfile.open(tarball) as tar: + tar.extractall() diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py new file mode 100755 index 000000000000..93e315ed930b --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py @@ -0,0 +1,6 @@ +import tarfile +import sys +import tempfile + +tar = tarfile.open(sys.argv[1]) +tar.extractall(path=tempfile.mkdtemp(), members=None) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py new file mode 100755 index 000000000000..9074c9f41f6b --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py @@ -0,0 +1,10 @@ +import tarfile +import sys + +class MKTar(tarfile.TarFile): + pass + +tarball = sys.argv[1] +with MKTar.open(name=tarball) as tar: + for entry in tar: + tar._extract_member(entry, entry.name) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py new file mode 100755 index 000000000000..a5c9a5ebf390 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py @@ -0,0 +1,36 @@ +import tarfile +import sys +from contextlib import closing, contextmanager +import subprocess +import os + +@contextmanager +def py2_tarxz(filename): + import tempfile + with tempfile.TemporaryFile() as tmp: + subprocess.check_call(["xz", "-dc", filename], stdout=tmp.fileno()) + tmp.seek(0) + with closing(tarfile.TarFile(fileobj=tmp)) as tf: + yield tf + +def unpack_tarball(tar_filename, dest): + # print('Unpacking %s into %s' % (os.path.basename(tar_filename), dest)) + # if sys.version_info[0] < 3 and tar_filename.endswith('.xz'): + # # Py 2.7 lacks lzma support + # tar_cm = py2_tarxz(tar_filename) + # else: + # + tar_cm = closing(tarfile.open(tar_filename)) + + base_dir = None + with tar_cm as tarc: + for member in tarc: + base_name = member.name.split('/')[0] + if base_dir is None: + base_dir = base_name + elif base_dir != base_name: + print('Unexpected path in %s: %s' % (tar_filename, base_name)) + tarc.extractall(dest) + return os.path.join(dest, base_dir) + +unpack_tarball(sys.argv[1], "/tmp/unpack") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py new file mode 100755 index 000000000000..c543965c7efa --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py @@ -0,0 +1,7 @@ +import tarfile +import sys + +tarball = sys.argv[1] +with tarfile.open(name=tarball) as tar: + for entry in tar: + tar._extract_member(entry, entry.name) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py new file mode 100755 index 000000000000..9cc84a3ccc19 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py @@ -0,0 +1,7 @@ +import tarfile +import sys + +tarball = sys.argv[1] +with tarfile.open(name=tarball) as tar: + for entry in tar: + tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py new file mode 100755 index 000000000000..a2837547704d --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py @@ -0,0 +1,6 @@ +import tarfile +import sys + +tarball = sys.argv[1] +tar = tarfile.open(tarball) +tar.extractall("/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/archive_malign.tar b/python/ql/src/experimental/Security/CWE-022bis/examples/archive_malign.tar new file mode 100644 index 0000000000000000000000000000000000000000..5a26012e119b7c12da19f3c3e7273db6d3902c49 GIT binary patch literal 10240 zcmeIy!H$A35P;#H_bKKHN+}i2yYUV735eE6f_5Wg^zpao$paDf!r^a7hO`}EJ~Fko zuoIUa{)*r35RP>*+=A7snm2~aqjApUP&TWFI4(I?2UCX1`=+XWpT1e-}RRLe~iNI9z&zYZlK#cwHQvZ9OPXqe@lm9w5m;RqC#XbZOKmY**5I_I{ j1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0V3`8{Zh2}5 literal 0 HcmV?d00001 diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/script.sh b/python/ql/src/experimental/Security/CWE-022bis/examples/script.sh new file mode 100644 index 000000000000..52c98c962c05 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-022bis/examples/script.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +mkdir -p /tmp/Sim4n6/ +FILE=/tmp/Sim4n6/sim4n6.txt + +for f in $(ls TarSlip_*.py); do + echo "$f"; + python3 "$f" archive_malign.tar; + if test -f "$FILE"; then + echo -e "\e[32mOK\e[0m" + rm "$FILE"; + else + echo -e "\e[31mNot OK\e[0m"; + fi +done; From 25a7fcffc0dd5393d2ef751c1633b5efe6ac7df5 Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Wed, 19 Oct 2022 16:01:34 +0100 Subject: [PATCH 02/10] Add an additional taint step --- .../experimental/Security/CWE-022bis/TarSlipImprov.ql | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql index 4871c21ee2c0..6fde4da13ed7 100755 --- a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql +++ b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql @@ -55,7 +55,7 @@ class AllTarfileOpens extends API::CallNode { class Configuration extends TaintTracking::Configuration { Configuration() { this = "TarSlip" } - override predicate isSource(DataFlow::Node source) { source instanceof AllTarfileOpens } + override predicate isSource(DataFlow::Node source) { source = tarfileOpen().getACall() } override predicate isSink(DataFlow::Node sink) { // A sink capturing method calls to `extractall` without `members` argument. @@ -99,6 +99,13 @@ class Configuration extends TaintTracking::Configuration { nodeFrom = call.getObject() and nodeTo = call ) + or + exists(DataFlow::CallCfgNode closing | + closing = API::moduleImport("contextlib").getMember("closing").getACall() and + nodeFrom = closing.getArg(0) and + nodeFrom = tarfileOpen().getACall() and + nodeTo = closing + ) } } From 9163cbec094a376504091b3591186e6aa01f14c2 Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Wed, 19 Oct 2022 16:08:49 +0100 Subject: [PATCH 03/10] Restrict the reach for an additional taint step --- python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql index 6fde4da13ed7..8e051bedfa75 100755 --- a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql +++ b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql @@ -97,6 +97,7 @@ class Configuration extends TaintTracking::Configuration { exists(AttrRead attr, MethodCallNode call | attr.accesses(nodeFrom, "getmembers") and nodeFrom = call.getObject() and + nodeFrom instanceof AllTarfileOpens and nodeTo = call ) or From 925f9d09e517e9be24b09812103d8d720395985a Mon Sep 17 00:00:00 2001 From: Sim4n6 Date: Fri, 21 Oct 2022 21:06:51 +0100 Subject: [PATCH 04/10] Update python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql Co-authored-by: yoff --- .../ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql index 8e051bedfa75..ec2efa867320 100755 --- a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql +++ b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql @@ -101,10 +101,10 @@ class Configuration extends TaintTracking::Configuration { nodeTo = call ) or - exists(DataFlow::CallCfgNode closing | + exists(API::CallNode closing | closing = API::moduleImport("contextlib").getMember("closing").getACall() and nodeFrom = closing.getArg(0) and - nodeFrom = tarfileOpen().getACall() and + nodeFrom = tarfileOpen().getReturn().getAValueReachingSink() and nodeTo = closing ) } From 31a6fb418168ba988a738f23c3ae4d479d9a3f32 Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Fri, 21 Oct 2022 21:28:20 +0100 Subject: [PATCH 05/10] Add TarSlip qlref for query-tests --- .../test/experimental/query-tests/Security/CWE-022/TarSlip.qlref | 1 + 1 file changed, 1 insertion(+) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref new file mode 100644 index 000000000000..fcf1288d01d6 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref @@ -0,0 +1 @@ +Security/CWE-022bis/TarSlipImprov.ql From 73190524955e9a13e2efaaa4ac40de5f69105417 Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Fri, 21 Oct 2022 21:47:00 +0100 Subject: [PATCH 06/10] Delete the examples/ --- .../CWE-022bis/examples/NoHIT_TarSlip_1.py | 19 --------- .../CWE-022bis/examples/NoHIT_TarSlip_2.py | 27 ------------- .../CWE-022bis/examples/NoHIT_TarSlip_3.py | 8 ---- .../CWE-022bis/examples/NoHIT_TarSlip_4.py | 13 ------- .../CWE-022bis/examples/NoHIT_TarSlip_5.py | 29 -------------- .../CWE-022bis/examples/NoHIT_TarSlip_6.py | 26 ------------- .../CWE-022bis/examples/NoHIT_TarSlip_7.py | 29 -------------- .../Security/CWE-022bis/examples/TarSlip_1.py | 18 --------- .../CWE-022bis/examples/TarSlip_10.py | 6 --- .../CWE-022bis/examples/TarSlip_11.py | 26 ------------- .../CWE-022bis/examples/TarSlip_12.py | 5 --- .../CWE-022bis/examples/TarSlip_13.py | 26 ------------- .../CWE-022bis/examples/TarSlip_14.py | 19 --------- .../CWE-022bis/examples/TarSlip_15.py | 26 ------------- .../CWE-022bis/examples/TarSlip_16.py | 8 ---- .../CWE-022bis/examples/TarSlip_17.py | 8 ---- .../CWE-022bis/examples/TarSlip_18.py | 8 ---- .../CWE-022bis/examples/TarSlip_19.py | 8 ---- .../Security/CWE-022bis/examples/TarSlip_2.py | 10 ----- .../CWE-022bis/examples/TarSlip_20.py | 9 ----- .../CWE-022bis/examples/TarSlip_21.py | 5 --- .../CWE-022bis/examples/TarSlip_22.py | 13 ------- .../CWE-022bis/examples/TarSlip_23.py | 6 --- .../CWE-022bis/examples/TarSlip_24.py | 26 ------------- .../CWE-022bis/examples/TarSlip_25.py | 5 --- .../CWE-022bis/examples/TarSlip_26.py | 20 ---------- .../CWE-022bis/examples/TarSlip_27.py | 8 ---- .../Security/CWE-022bis/examples/TarSlip_3.py | 6 --- .../Security/CWE-022bis/examples/TarSlip_4.py | 6 --- .../Security/CWE-022bis/examples/TarSlip_5.py | 10 ----- .../Security/CWE-022bis/examples/TarSlip_6.py | 36 ------------------ .../Security/CWE-022bis/examples/TarSlip_7.py | 7 ---- .../Security/CWE-022bis/examples/TarSlip_8.py | 7 ---- .../Security/CWE-022bis/examples/TarSlip_9.py | 6 --- .../CWE-022bis/examples/archive_malign.tar | Bin 10240 -> 0 bytes .../Security/CWE-022bis/examples/script.sh | 15 -------- 36 files changed, 504 deletions(-) delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py delete mode 100755 python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py delete mode 100644 python/ql/src/experimental/Security/CWE-022bis/examples/archive_malign.tar delete mode 100644 python/ql/src/experimental/Security/CWE-022bis/examples/script.sh diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py deleted file mode 100755 index 660ff37bd662..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_1.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys -import tarfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - result = [] - for member in tar: - if ".." in member.name: - raise ValueError("Path in member name !!!") - result.append(member) - path = sys.argv[2] - #print("files are extracted to: ", path) - tar.extractall(path=path, members=result) - tar.close() - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py deleted file mode 100755 index afeb9ac26bd7..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_2.py +++ /dev/null @@ -1,27 +0,0 @@ -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) - tar.close() - - -def members_filter(tarfile): - result = [] - for member in tarfile: - if '../' in member.name: - print('Member name container directory traversal sequence') - continue - elif member.issym() or member.islnk(): - print('Symlink to external resource') - continue - result.append(member) - return result - - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py deleted file mode 100755 index 6911f7bf6298..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_3.py +++ /dev/null @@ -1,8 +0,0 @@ -import tarfile -import sys - -with tarfile.open(sys.argv[1]) as tar: - for entry in tar: - if ".." in entry.name: - raise ValueError("Illegal tar archive entry") - tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py deleted file mode 100755 index 03f769daf8ab..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_4.py +++ /dev/null @@ -1,13 +0,0 @@ -import tarfile -import sys -import os - -def _validate_archive_name(name, target): - if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): - raise ValueError(f"Provided language pack contains invalid name {name}") - -with tarfile.open(sys.argv[1]) as tar: - target = "/tmp/unpack" - for entry in tar: - _validate_archive_name(entry.name, target) - tar.extract(entry, target) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py deleted file mode 100755 index 16997f350eee..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_5.py +++ /dev/null @@ -1,29 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) - tar.close() - - -def members_filter(tarfile): - result = [] - for member in tarfile.getmembers(): - if '../' in member.name: - print('Member name container directory traversal sequence') - continue - elif (member.issym() or member.islnk()) and ('../' in member.linkname): - print('Symlink to external resource') - continue - result.append(member) - return result - - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py deleted file mode 100755 index 3301dc4e35c2..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_6.py +++ /dev/null @@ -1,26 +0,0 @@ -# https://github.com/OctoPrint/OctoPrint/ - -import sys -import tarfile -import os - -def _validate_tar_info(info, target): - _validate_archive_name(info.name, target) - if not (info.isfile() or info.isdir()): - raise ValueError("Provided language pack contains invalid file type") - -def _validate_archive_name(name, target): - if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): - raise ValueError(f"Provided language pack contains invalid name {name}") - -target = "/tmp/unpack" - -with tarfile.open(sys.argv[1], "r") as tar: - - # sanity check - for info in tar.getmembers(): - _validate_tar_info(info, target) - - # unpack everything - tar.extractall(target) - diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py b/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py deleted file mode 100755 index b62fa3e84291..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/NoHIT_TarSlip_7.py +++ /dev/null @@ -1,29 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) - tar.close() - - -def members_filter(tarfile): - result = [] - for member in tarfile.getmembers(): - if '../' in member.name: - print('Member name container directory traversal sequence') - continue - elif member.issym() or member.islnk(): - print('Symlink to external resource') - continue - result.append(member) - return result - - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py deleted file mode 100755 index 212baf4877c8..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_1.py +++ /dev/null @@ -1,18 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tarf = tar.getmembers() - for f in tarf: - if not f.issym(): - tar.extractall(path=tempfile.mkdtemp(), members=[f]) - tar.close() - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py deleted file mode 100755 index 08cf77ad6ce8..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_10.py +++ /dev/null @@ -1,6 +0,0 @@ -import tarfile -import sys - -tarball = sys.argv[1] -with tarfile.open(tarball, "r") as tar: - tar.extractall(path="/tmp/unpack/", members=tar) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py deleted file mode 100755 index d007fb2bba50..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_11.py +++ /dev/null @@ -1,26 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) - tar.close() - - -def members_filter(tarfile): - result = [] - for member in tarfile.getmembers(): - if member.issym() or member.islnk(): - print('Symlink to external resource') - continue - result.append(member) - return result - - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py deleted file mode 100755 index 6633ff013712..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_12.py +++ /dev/null @@ -1,5 +0,0 @@ -import tarfile -import sys - -with tarfile.open(sys.argv[1], "r") as tar: - tar.extractall(path="/tmp/unpack") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py deleted file mode 100755 index bd0c741e50e3..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_13.py +++ /dev/null @@ -1,26 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) - tar.close() - - -def members_filter(tarfile): - result = [] - for member in tarfile.getmembers(): - if member.issym(): - print('Symlink to external resource') - continue - result.append(member) - return result - - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py deleted file mode 100755 index 91b9c710c5ef..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_14.py +++ /dev/null @@ -1,19 +0,0 @@ -# https://github.com/tensorflow/tensor2tensor -import tarfile -import os.path -import sys - -# provie the malign archive -filename = sys.argv[1] -tmp_dir = "/tmp/" - -read_type = "r:gz" if filename.endswith("tgz") else "r" -with tarfile.open(filename, read_type) as corpus_tar: - # Create a subset of files that don't already exist. - # tarfile.extractall errors when encountering an existing file - # and tarfile.extract is extremely slow - members = [] - for f in corpus_tar: - if not os.path.isfile(os.path.join(tmp_dir, f.name)): - members.append(f) - corpus_tar.extractall(tmp_dir, members=members) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py deleted file mode 100755 index 675540041b8a..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_15.py +++ /dev/null @@ -1,26 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) - tar.close() - - -def members_filter(tarfile): - result = [] - for member in tarfile.getmembers(): - if not member.isreg(): - print('Symlink to external resource') - continue - result.append(member) - return result - - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py deleted file mode 100755 index 27eb760909ad..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_16.py +++ /dev/null @@ -1,8 +0,0 @@ -from fileinput import filename -import tarfile -import os.path -import sys - -archive_path = sys.argv[1] -target_dir = "/tmp/unpack" -tarfile.open(archive_path, "r").extractall(path=target_dir) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py deleted file mode 100755 index 0508668e98ed..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_17.py +++ /dev/null @@ -1,8 +0,0 @@ -import tarfile -import sys - -tarball = sys.argv[1] -with tarfile.open(tarball) as tar: - for entry in tar: - if entry.isfile(): - tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py deleted file mode 100755 index 77d1fc2b2b82..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_18.py +++ /dev/null @@ -1,8 +0,0 @@ -import tarfile -import sys - -with tarfile.open(sys.argv[1]) as tar: - for entry in tar: - if entry.name.startswith("/"): - raise ValueError("Illegal tar archive entry") - tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py deleted file mode 100755 index 429be70d0210..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_19.py +++ /dev/null @@ -1,8 +0,0 @@ -import tarfile -import sys - -tarball = sys.argv[1] -with tarfile.TarFile(tarball, mode="r") as tar: - for entry in tar: - if entry.isfile(): - tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py deleted file mode 100755 index 1e7717012e3d..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_2.py +++ /dev/null @@ -1,10 +0,0 @@ -from tarfile import TarFile -import sys - -class MKTar(TarFile): - pass - -tarball = sys.argv[1] -with MKTar.open(name=tarball) as tar: - for entry in tar: - tar._extract_member(entry, entry.name) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py deleted file mode 100755 index b8e8542abda0..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_20.py +++ /dev/null @@ -1,9 +0,0 @@ -import tarfile -import sys -import os - -with tarfile.open(sys.argv[1]) as tar: - for entry in tar: - if os.path.isabs(entry.name): - raise ValueError("Illegal tar archive entry") - tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py deleted file mode 100755 index 4024744ad9af..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_21.py +++ /dev/null @@ -1,5 +0,0 @@ -import tarfile -import sys - -with tarfile.TarFile(sys.argv[1], mode="r") as tar: - tar.extractall(path="/tmp/unpack") \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py deleted file mode 100755 index 1e9cbd1ed5a0..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_22.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=tar.getmembers()) - tar.close() - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py deleted file mode 100755 index c433ad6d96e2..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_23.py +++ /dev/null @@ -1,6 +0,0 @@ -import tarfile -import sys -import tempfile - -tar = tarfile.open(sys.argv[1]) -tar.extractall(path=tempfile.mkdtemp(), members=None) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py deleted file mode 100755 index 13e5771caebb..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_24.py +++ /dev/null @@ -1,26 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - tar.extractall(path=tempfile.mkdtemp(), members=members_filter(tar)) - tar.close() - - -def members_filter(tarfile): - result = [] - for member in tarfile: - if member.issym() or member.islnk(): - print('Symlink to external resource') - continue - result.append(member) - return result - - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py deleted file mode 100755 index 8c21d3a2f0b1..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_25.py +++ /dev/null @@ -1,5 +0,0 @@ -import tarfile -import sys - -with tarfile.TarFile(sys.argv[1], mode="r") as tar: - tar.extractall(path="/tmp/unpack/", members=tar) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py deleted file mode 100755 index 911c8906e734..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_26.py +++ /dev/null @@ -1,20 +0,0 @@ -# https://github.com/PyCQA/bandit - -import sys -import tarfile -import tempfile - -def managed_members_archive_handler(filename): - tar = tarfile.open(filename) - result = [] - for member in tar: - if member.issym(): - raise ValueError("But it is a symlink") - result.append(member) - tar.extractall(path=tempfile.mkdtemp(), members=result) - tar.close() - -if __name__ == "__main__": - if len(sys.argv) > 1: - filename = sys.argv[1] - managed_members_archive_handler(filename) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py deleted file mode 100755 index a6434d87f3d3..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_27.py +++ /dev/null @@ -1,8 +0,0 @@ -from fileinput import filename -import tarfile -import os.path -import sys - -archive_path = sys.argv[1] -target_dir = "/tmp/unpack" -tarfile.TarFile(sys.argv[1], mode="r").extractall(path=target_dir) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py deleted file mode 100755 index 2e56a0bf88a7..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_3.py +++ /dev/null @@ -1,6 +0,0 @@ -import tarfile -import sys - -tarball = sys.argv[1] -with tarfile.open(tarball) as tar: - tar.extractall() diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py deleted file mode 100755 index 93e315ed930b..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_4.py +++ /dev/null @@ -1,6 +0,0 @@ -import tarfile -import sys -import tempfile - -tar = tarfile.open(sys.argv[1]) -tar.extractall(path=tempfile.mkdtemp(), members=None) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py deleted file mode 100755 index 9074c9f41f6b..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_5.py +++ /dev/null @@ -1,10 +0,0 @@ -import tarfile -import sys - -class MKTar(tarfile.TarFile): - pass - -tarball = sys.argv[1] -with MKTar.open(name=tarball) as tar: - for entry in tar: - tar._extract_member(entry, entry.name) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py deleted file mode 100755 index a5c9a5ebf390..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_6.py +++ /dev/null @@ -1,36 +0,0 @@ -import tarfile -import sys -from contextlib import closing, contextmanager -import subprocess -import os - -@contextmanager -def py2_tarxz(filename): - import tempfile - with tempfile.TemporaryFile() as tmp: - subprocess.check_call(["xz", "-dc", filename], stdout=tmp.fileno()) - tmp.seek(0) - with closing(tarfile.TarFile(fileobj=tmp)) as tf: - yield tf - -def unpack_tarball(tar_filename, dest): - # print('Unpacking %s into %s' % (os.path.basename(tar_filename), dest)) - # if sys.version_info[0] < 3 and tar_filename.endswith('.xz'): - # # Py 2.7 lacks lzma support - # tar_cm = py2_tarxz(tar_filename) - # else: - # - tar_cm = closing(tarfile.open(tar_filename)) - - base_dir = None - with tar_cm as tarc: - for member in tarc: - base_name = member.name.split('/')[0] - if base_dir is None: - base_dir = base_name - elif base_dir != base_name: - print('Unexpected path in %s: %s' % (tar_filename, base_name)) - tarc.extractall(dest) - return os.path.join(dest, base_dir) - -unpack_tarball(sys.argv[1], "/tmp/unpack") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py deleted file mode 100755 index c543965c7efa..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_7.py +++ /dev/null @@ -1,7 +0,0 @@ -import tarfile -import sys - -tarball = sys.argv[1] -with tarfile.open(name=tarball) as tar: - for entry in tar: - tar._extract_member(entry, entry.name) diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py deleted file mode 100755 index 9cc84a3ccc19..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_8.py +++ /dev/null @@ -1,7 +0,0 @@ -import tarfile -import sys - -tarball = sys.argv[1] -with tarfile.open(name=tarball) as tar: - for entry in tar: - tar.extract(entry, "/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py b/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py deleted file mode 100755 index a2837547704d..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/TarSlip_9.py +++ /dev/null @@ -1,6 +0,0 @@ -import tarfile -import sys - -tarball = sys.argv[1] -tar = tarfile.open(tarball) -tar.extractall("/tmp/unpack/") diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/archive_malign.tar b/python/ql/src/experimental/Security/CWE-022bis/examples/archive_malign.tar deleted file mode 100644 index 5a26012e119b7c12da19f3c3e7273db6d3902c49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10240 zcmeIy!H$A35P;#H_bKKHN+}i2yYUV735eE6f_5Wg^zpao$paDf!r^a7hO`}EJ~Fko zuoIUa{)*r35RP>*+=A7snm2~aqjApUP&TWFI4(I?2UCX1`=+XWpT1e-}RRLe~iNI9z&zYZlK#cwHQvZ9OPXqe@lm9w5m;RqC#XbZOKmY**5I_I{ j1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0V3`8{Zh2}5 diff --git a/python/ql/src/experimental/Security/CWE-022bis/examples/script.sh b/python/ql/src/experimental/Security/CWE-022bis/examples/script.sh deleted file mode 100644 index 52c98c962c05..000000000000 --- a/python/ql/src/experimental/Security/CWE-022bis/examples/script.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -mkdir -p /tmp/Sim4n6/ -FILE=/tmp/Sim4n6/sim4n6.txt - -for f in $(ls TarSlip_*.py); do - echo "$f"; - python3 "$f" archive_malign.tar; - if test -f "$FILE"; then - echo -e "\e[32mOK\e[0m" - rm "$FILE"; - else - echo -e "\e[31mNot OK\e[0m"; - fi -done; From 7d60f1f1c8f18c57d50d47cd56a58e564939a7ba Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Fri, 21 Oct 2022 22:13:47 +0100 Subject: [PATCH 07/10] Modified the QL ref file and add TarSlip examples --- .../Security/CWE-022/TarSlip.qlref | 2 +- .../Security/CWE-022/TarSlipImprov.py | 316 ++++++++++++++++++ 2 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-022/TarSlipImprov.py diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref index fcf1288d01d6..a518196b6982 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.qlref @@ -1 +1 @@ -Security/CWE-022bis/TarSlipImprov.ql +experimental/Security/CWE-022bis/TarSlipImprov.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlipImprov.py b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlipImprov.py new file mode 100644 index 000000000000..15bc66b4aea5 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlipImprov.py @@ -0,0 +1,316 @@ +#!/usr/bin/python + +import sys +import tarfile +import tempfile +import os +from tarfile import TarFile +from contextlib import closing, contextmanager +import subprocess +import os.path + +unsafe_filename_tar = sys.argv[2] +safe_filename_tar = "safe_path.tar" + +tar = tarfile.open(unsafe_filename_tar) +result = [] +for member in tar: + if ".." in member.name: + raise ValueError("Path in member name !!!") + result.append(member) +path = unsafe_filename_tar +tar.extractall(path=path, members=result) +tar.close() + + +def members_filter1(tarfile): + result = [] + for member in tarfile: + if '../' in member.name: + print('Member name container directory traversal sequence') + continue + elif member.issym() or member.islnk(): + print('Symlink to external resource') + continue + result.append(member) + return result + +tar = tarfile.open(unsafe_filename_tar) +tar.extractall(path=tempfile.mkdtemp(), members=members_filter1(tar)) +tar.close() + + +with tarfile.open(unsafe_filename_tar) as tar: + for entry in tar: + if ".." in entry.name: + raise ValueError("Illegal tar archive entry") + tar.extract(entry, "/tmp/unpack/") + + +def _validate_archive_name(name, target): + if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): + raise ValueError(f"Provided language pack contains invalid name {name}") + +with tarfile.open(unsafe_filename_tar) as tar: + target = "/tmp/unpack" + for entry in tar: + _validate_archive_name(entry.name, target) + tar.extract(entry, target) + + +def members_filter2(tarfile): + result = [] + for member in tarfile.getmembers(): + if '../' in member.name: + print('Member name container directory traversal sequence') + continue + elif (member.issym() or member.islnk()) and ('../' in member.linkname): + print('Symlink to external resource') + continue + result.append(member) + return result + +tar = tarfile.open(unsafe_filename_tar) +tar.extractall(path=tempfile.mkdtemp(), members=members_filter2(tar)) +tar.close() + + +def _validate_tar_info(info, target): + _validate_archive_name(info.name, target) + if not (info.isfile() or info.isdir()): + raise ValueError("Provided language pack contains invalid file type") + +def _validate_archive_name(name, target): + if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): + raise ValueError(f"Provided language pack contains invalid name {name}") + +target = "/tmp/unpack" +with tarfile.open(unsafe_filename_tar, "r") as tar: + for info in tar.getmembers(): + _validate_tar_info(info, target) + tar.extractall(target) + + +def members_filter3(tarfile): + result = [] + for member in tarfile.getmembers(): + if '../' in member.name: + print('Member name container directory traversal sequence') + continue + elif member.issym() or member.islnk(): + print('Symlink to external resource') + continue + result.append(member) + return result + +tar = tarfile.open(unsafe_filename_tar) +tar.extractall(path=tempfile.mkdtemp(), members=members_filter3(tar)) +tar.close() + + +tar = tarfile.open(unsafe_filename_tar) +tarf = tar.getmembers() +for f in tarf: + if not f.issym(): + tar.extractall(path=tempfile.mkdtemp(), members=[f]) +tar.close() + + +class MKTar(TarFile): + pass + +tarball = unsafe_filename_tar +with MKTar.open(name=tarball) as tar: + for entry in tar: + tar._extract_member(entry, entry.name) + + +tarball = unsafe_filename_tar +with tarfile.open(tarball) as tar: + tar.extractall() + + +tar = tarfile.open(unsafe_filename_tar) +tar.extractall(path=tempfile.mkdtemp(), members=None) + + +class MKTar(tarfile.TarFile): + pass + +tarball = unsafe_filename_tar +with MKTar.open(name=tarball) as tar: + for entry in tar: + tar._extract_member(entry, entry.name) + + +@contextmanager +def py2_tarxz(filename): + with tempfile.TemporaryFile() as tmp: + subprocess.check_call(["xz", "-dc", filename], stdout=tmp.fileno()) + tmp.seek(0) + with closing(tarfile.TarFile(fileobj=tmp)) as tf: + yield tf + +def unpack_tarball(tar_filename, dest): + if sys.version_info[0] < 3 and tar_filename.endswith('.xz'): + # Py 2.7 lacks lzma support + tar_cm = py2_tarxz(tar_filename) + else: + tar_cm = closing(tarfile.open(tar_filename)) + + base_dir = None + with tar_cm as tarc: + for member in tarc: + base_name = member.name.split('/')[0] + if base_dir is None: + base_dir = base_name + elif base_dir != base_name: + print('Unexpected path in %s: %s' % (tar_filename, base_name)) + tarc.extractall(dest) + return os.path.join(dest, base_dir) + +unpack_tarball(unsafe_filename_tar, "/tmp/unpack") + + +tarball = unsafe_filename_tar +with tarfile.open(name=tarball) as tar: + for entry in tar: + tar._extract_member(entry, entry.name) + + +tarball = unsafe_filename_tar +with tarfile.open(name=tarball) as tar: + for entry in tar: + tar.extract(entry, "/tmp/unpack/") + + +tarball = unsafe_filename_tar +tar = tarfile.open(tarball) +tar.extractall("/tmp/unpack/") + + +tarball = unsafe_filename_tar +with tarfile.open(tarball, "r") as tar: + tar.extractall(path="/tmp/unpack/", members=tar) + + +def members_filter4(tarfile): + result = [] + for member in tarfile.getmembers(): + if member.issym() or member.islnk(): + print('Symlink to external resource') + continue + result.append(member) + return result +tar = tarfile.open(unsafe_filename_tar) +tar.extractall(path=tempfile.mkdtemp(), members=members_filter4(tar)) +tar.close() + + +with tarfile.open(unsafe_filename_tar, "r") as tar: + tar.extractall(path="/tmp/unpack") + + +def members_filter5(tarfile): + result = [] + for member in tarfile.getmembers(): + if member.issym(): + print('Symlink to external resource') + continue + result.append(member) + return result +tar = tarfile.open(unsafe_filename_tar) +tar.extractall(path=tempfile.mkdtemp(), members=members_filter5(tar)) +tar.close() + + +filename = unsafe_filename_tar +tmp_dir = "/tmp/" + +read_type = "r:gz" if filename.endswith("tgz") else "r" +with tarfile.open(filename, read_type) as corpus_tar: + members = [] + for f in corpus_tar: + if not os.path.isfile(os.path.join(tmp_dir, f.name)): + members.append(f) + corpus_tar.extractall(tmp_dir, members=members) + + +def members_filter6(tarfile): + result = [] + for member in tarfile.getmembers(): + if not member.isreg(): + print('Symlink to external resource') + continue + result.append(member) + return result +tar = tarfile.open(filename) +tar.extractall(path=tempfile.mkdtemp(), members=members_filter6(tar)) +tar.close() + + +archive_path = unsafe_filename_tar +target_dir = "/tmp/unpack" +tarfile.open(archive_path, "r").extractall(path=target_dir) + + +tarball = unsafe_filename_tar +with tarfile.open(tarball) as tar: + for entry in tar: + if entry.isfile(): + tar.extract(entry, "/tmp/unpack/") + + +with tarfile.open(unsafe_filename_tar) as tar: + for entry in tar: + if entry.name.startswith("/"): + raise ValueError("Illegal tar archive entry") + tar.extract(entry, "/tmp/unpack/") + +tarball = unsafe_filename_tar +with tarfile.TarFile(tarball, mode="r") as tar: + for entry in tar: + if entry.isfile(): + tar.extract(entry, "/tmp/unpack/") + +with tarfile.open(unsafe_filename_tar) as tar: + for entry in tar: + if os.path.isabs(entry.name): + raise ValueError("Illegal tar archive entry") + tar.extract(entry, "/tmp/unpack/") + + +with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: + tar.extractall(path="/tmp/unpack") + + +tar = tarfile.open(filename) +tar.extractall(path=tempfile.mkdtemp(), members=tar.getmembers()) +tar.close() + + +tar = tarfile.open(unsafe_filename_tar) +tar.extractall(path=tempfile.mkdtemp(), members=None) + + +tar.extractall(path=tempfile.mkdtemp(), members=members_filter4(tar)) +tar.close() + + +with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: + tar.extractall(path="/tmp/unpack/", members=tar) + + +tar = tarfile.open(unsafe_filename_tar) +result = [] +for member in tar: + if member.issym(): + raise ValueError("But it is a symlink") + result.append(member) +tar.extractall(path=tempfile.mkdtemp(), members=result) +tar.close() + + +archive_path = unsafe_filename_tar +target_dir = "/tmp/unpack" +tarfile.TarFile(unsafe_filename_tar, mode="r").extractall(path=target_dir) \ No newline at end of file From 0f4426803891b3a66f890787cb672f8b04768162 Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Fri, 21 Oct 2022 22:14:55 +0100 Subject: [PATCH 08/10] Add expected test results --- .../Security/CWE-022/TarSlip.expected | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected new file mode 100644 index 000000000000..9ba7097396b6 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected @@ -0,0 +1,144 @@ +edges +| TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:17:5:17:10 | GSSA Variable member | +| TarSlipImprov.py:17:5:17:10 | GSSA Variable member | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | +| TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:28:9:28:14 | SSA variable member | +| TarSlipImprov.py:28:9:28:14 | SSA variable member | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | +| TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | +| TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | +| TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | +| TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:56:9:56:13 | GSSA Variable entry | +| TarSlipImprov.py:56:9:56:13 | GSSA Variable entry | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | +| TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | +| TarSlipImprov.py:111:7:111:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:115:9:115:11 | ControlFlowNode for tar | +| TarSlipImprov.py:123:6:123:29 | ControlFlowNode for Attribute() | TarSlipImprov.py:124:9:124:13 | GSSA Variable entry | +| TarSlipImprov.py:124:9:124:13 | GSSA Variable entry | TarSlipImprov.py:125:36:125:40 | ControlFlowNode for entry | +| TarSlipImprov.py:129:6:129:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | +| TarSlipImprov.py:133:7:133:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | +| TarSlipImprov.py:141:6:141:29 | ControlFlowNode for Attribute() | TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | +| TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | +| TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:177:9:177:13 | GSSA Variable entry | +| TarSlipImprov.py:177:9:177:13 | GSSA Variable entry | TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | +| TarSlipImprov.py:182:6:182:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:183:9:183:13 | GSSA Variable entry | +| TarSlipImprov.py:183:9:183:13 | GSSA Variable entry | TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | +| TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | +| TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | +| TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | +| TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:233:9:233:9 | GSSA Variable f | +| TarSlipImprov.py:233:9:233:9 | GSSA Variable f | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | +| TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | +| TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | +| TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:265:9:265:13 | GSSA Variable entry | +| TarSlipImprov.py:265:9:265:13 | GSSA Variable entry | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | +| TarSlipImprov.py:271:6:271:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:272:9:272:13 | GSSA Variable entry | +| TarSlipImprov.py:272:9:272:13 | GSSA Variable entry | TarSlipImprov.py:274:25:274:29 | ControlFlowNode for entry | +| TarSlipImprov.py:276:6:276:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:277:9:277:13 | GSSA Variable entry | +| TarSlipImprov.py:277:9:277:13 | GSSA Variable entry | TarSlipImprov.py:280:21:280:25 | ControlFlowNode for entry | +| TarSlipImprov.py:283:6:283:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:284:5:284:7 | ControlFlowNode for tar | +| TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | +| TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | +| TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | +| TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:306:5:306:10 | GSSA Variable member | +| TarSlipImprov.py:306:5:306:10 | GSSA Variable member | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | +nodes +| TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:17:5:17:10 | GSSA Variable member | semmle.label | GSSA Variable member | +| TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | +| TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | semmle.label | ControlFlowNode for tarfile | +| TarSlipImprov.py:28:9:28:14 | SSA variable member | semmle.label | SSA variable member | +| TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | +| TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | semmle.label | ControlFlowNode for members_filter1() | +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:44:9:44:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:56:9:56:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:111:7:111:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:115:9:115:11 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:123:6:123:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:124:9:124:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:125:36:125:40 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:129:6:129:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:133:7:133:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:141:6:141:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:142:9:142:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:177:9:177:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:182:6:182:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:183:9:183:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:233:9:233:9 | GSSA Variable f | semmle.label | GSSA Variable f | +| TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | semmle.label | ControlFlowNode for members | +| TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:259:9:259:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:265:9:265:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:271:6:271:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:272:9:272:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:274:25:274:29 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:276:6:276:38 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:277:9:277:13 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| TarSlipImprov.py:280:21:280:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| TarSlipImprov.py:283:6:283:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:284:5:284:7 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:306:5:306:10 | GSSA Variable member | semmle.label | GSSA Variable member | +| TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | +| TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +subpaths +| TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | +#select +| TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:15:7:15:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:22:35:22:40 | ControlFlowNode for result | ControlFlowNode for result | +| TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:38:7:38:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | ControlFlowNode for members_filter1() | +| TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:43:6:43:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:47:21:47:25 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:54:6:54:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:58:21:58:25 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:88:6:88:43 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:91:5:91:7 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:115:9:115:11 | ControlFlowNode for tar | TarSlipImprov.py:111:7:111:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:115:9:115:11 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:111:7:111:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:115:9:115:11 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:125:36:125:40 | ControlFlowNode for entry | TarSlipImprov.py:123:6:123:29 | ControlFlowNode for Attribute() | TarSlipImprov.py:125:36:125:40 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:123:6:123:29 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:125:36:125:40 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | TarSlipImprov.py:129:6:129:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:129:6:129:26 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:130:5:130:7 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | TarSlipImprov.py:133:7:133:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:133:7:133:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:134:1:134:3 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | TarSlipImprov.py:141:6:141:29 | ControlFlowNode for Attribute() | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:141:6:141:29 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:143:36:143:40 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:176:6:176:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:178:36:178:40 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | TarSlipImprov.py:182:6:182:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:182:6:182:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:184:21:184:25 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:188:7:188:27 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:189:1:189:3 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:193:6:193:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:194:49:194:51 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:210:6:210:43 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:211:5:211:7 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:231:6:231:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:236:44:236:50 | ControlFlowNode for members | ControlFlowNode for members | +| TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:254:1:254:31 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | +| TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:258:6:258:26 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:261:25:261:29 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:264:6:264:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:268:21:268:25 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:274:25:274:29 | ControlFlowNode for entry | TarSlipImprov.py:271:6:271:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:274:25:274:29 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:271:6:271:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:274:25:274:29 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:280:21:280:25 | ControlFlowNode for entry | TarSlipImprov.py:276:6:276:38 | ControlFlowNode for Attribute() | TarSlipImprov.py:280:21:280:25 | ControlFlowNode for entry | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:276:6:276:38 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:280:21:280:25 | ControlFlowNode for entry | ControlFlowNode for entry | +| TarSlipImprov.py:284:5:284:7 | ControlFlowNode for tar | TarSlipImprov.py:283:6:283:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:284:5:284:7 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:283:6:283:51 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:284:5:284:7 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:287:7:287:28 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:288:49:288:51 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:292:7:292:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:293:1:293:3 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:300:6:300:51 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:301:49:301:51 | ControlFlowNode for tar | ControlFlowNode for tar | +| TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:304:7:304:39 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | ControlFlowNode for result | +| TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | Extraction of tarfile from $@ to a potentially untrusted source $@. | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | ControlFlowNode for Attribute() | From fdbed2a0196825af750d96c73352fe25aca1fdf9 Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Sat, 22 Oct 2022 09:34:57 +0100 Subject: [PATCH 09/10] Add expected test results without considering inStdLib files. --- .../experimental/query-tests/Security/CWE-022/TarSlip.expected | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected index 9ba7097396b6..774b0005433e 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-022/TarSlip.expected @@ -111,7 +111,6 @@ nodes | TarSlipImprov.py:306:5:306:10 | GSSA Variable member | semmle.label | GSSA Variable member | | TarSlipImprov.py:310:49:310:54 | ControlFlowNode for result | semmle.label | ControlFlowNode for result | | TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TarSlipImprov.py:316:1:316:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | subpaths | TarSlipImprov.py:39:65:39:67 | ControlFlowNode for tar | TarSlipImprov.py:26:21:26:27 | ControlFlowNode for tarfile | TarSlipImprov.py:36:12:36:17 | ControlFlowNode for result | TarSlipImprov.py:39:49:39:68 | ControlFlowNode for members_filter1() | #select From 92a384610201c15c23134cb8426ae6c83f90f859 Mon Sep 17 00:00:00 2001 From: ALJI Mohamed Date: Sat, 22 Oct 2022 09:35:55 +0100 Subject: [PATCH 10/10] Fix query to omit sinks within std lib files --- .../Security/CWE-022bis/TarSlipImprov.ql | 72 ++++++++++--------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql index ec2efa867320..e614c1a3d78a 100755 --- a/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql +++ b/python/ql/src/experimental/Security/CWE-022bis/TarSlipImprov.ql @@ -49,6 +49,7 @@ class AllTarfileOpens extends API::CallNode { ) } } + /** * A taint-tracking configuration for detecting more "TarSlip" vulnerabilities. */ @@ -58,39 +59,44 @@ class Configuration extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source = tarfileOpen().getACall() } override predicate isSink(DataFlow::Node sink) { - // A sink capturing method calls to `extractall` without `members` argument. - // For a call to `file.extractall` without `members` argument, `file` is considered a sink. - exists(MethodCallNode call , AllTarfileOpens atfo| - call = atfo.getReturn().getMember("extractall").getACall() and - not exists(Node arg | arg = call.getArgByName("members")) and - sink = call.getObject() - ) - or - // A sink capturing method calls to `extractall` with `members` argument. - // For a call to `file.extractall` with `members` argument, `file` is considered a sink if not - // a the `members` argument contains a NameConstant as None, a List or call to the method `getmembers`. - // Otherwise, the argument of `members` is considered a sink. - exists(MethodCallNode call, Node arg, AllTarfileOpens atfo| - call = atfo.getReturn().getMember("extractall").getACall() and - arg = call.getArgByName("members") and - if - arg.asCfgNode() instanceof NameConstantNode or - arg.asCfgNode() instanceof ListNode - then sink = call.getObject() - else - if arg.(MethodCallNode).getMethodName() = "getmembers" - then sink = arg.(MethodCallNode).getObject() - else sink = call.getArgByName("members") - ) - or - // An argument to `extract` is considered a sink. - exists(AllTarfileOpens atfo | sink = atfo.getReturn().getMember("extract").getACall().getArg(0)) - or - //An argument to `_extract_member` is considered a sink. - exists(MethodCallNode call, AllTarfileOpens atfo | - call = atfo.getReturn().getMember("_extract_member").getACall() and - call.getArg(1).(AttrRead).accesses(sink, "name") - ) + ( + // A sink capturing method calls to `extractall` without `members` argument. + // For a call to `file.extractall` without `members` argument, `file` is considered a sink. + exists(MethodCallNode call, AllTarfileOpens atfo | + call = atfo.getReturn().getMember("extractall").getACall() and + not exists(Node arg | arg = call.getArgByName("members")) and + sink = call.getObject() + ) + or + // A sink capturing method calls to `extractall` with `members` argument. + // For a call to `file.extractall` with `members` argument, `file` is considered a sink if not + // a the `members` argument contains a NameConstant as None, a List or call to the method `getmembers`. + // Otherwise, the argument of `members` is considered a sink. + exists(MethodCallNode call, Node arg, AllTarfileOpens atfo | + call = atfo.getReturn().getMember("extractall").getACall() and + arg = call.getArgByName("members") and + if + arg.asCfgNode() instanceof NameConstantNode or + arg.asCfgNode() instanceof ListNode + then sink = call.getObject() + else + if arg.(MethodCallNode).getMethodName() = "getmembers" + then sink = arg.(MethodCallNode).getObject() + else sink = call.getArgByName("members") + ) + or + // An argument to `extract` is considered a sink. + exists(AllTarfileOpens atfo | + sink = atfo.getReturn().getMember("extract").getACall().getArg(0) + ) + or + //An argument to `_extract_member` is considered a sink. + exists(MethodCallNode call, AllTarfileOpens atfo | + call = atfo.getReturn().getMember("_extract_member").getACall() and + call.getArg(1).(AttrRead).accesses(sink, "name") + ) + ) and + not sink.getScope().getLocation().getFile().inStdlib() } override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {