trailofbits.python.tarfile-extractall-traversal.tarfile-extractall-traversal
trailofbits
Author
232
Download Count*
License
Possible path traversal through tarfile.open($PATH).extractall()
if the source tar is controlled by an attacker
Run Locally
Run in CI
Defintion
rules:
- id: tarfile-extractall-traversal
message: Possible path traversal through `tarfile.open($PATH).extractall()` if
the source tar is controlled by an attacker
languages:
- python
severity: ERROR
metadata:
category: security
cwe: "CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path
Traversal')"
subcategory:
- vuln
confidence: MEDIUM
likelihood: MEDIUM
impact: MEDIUM
technology:
- --no-technology--
description: Potential path traversal in call to `extractall` for a `tarfile`
references:
- https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.extractall
license: AGPL-3.0 license
vulnerability_class:
- Path Traversal
patterns:
- pattern-either:
- pattern: |
with tarfile.open(...) as $TAR:
...
$TAR.extractall(...)
- pattern: |
tarfile.open(...).extractall(...)
- pattern: |
$TAR = tarfile.open(...)
...
$TAR.extractall(...)
- pattern-not: |
with tarfile.open(...) as $TAR:
...
$TAR.extractall(..., members=$MEMBERS, ...)
- pattern-not: |
tarfile.open(...).extractall(..., members=$MEMBERS, ...)
- pattern-not: |
$TAR = tarfile.open(...)
...
$TAR.extractall(..., members=$MEMBERS, ...)
Examples
tarfile-extractall-traversal.py
import argparse
import tarfile
def get_parser():
parser = argparse.ArgumentParser(description='Process zip files.')
parser.add_argument('--path', type=str, required=True,
help='Path to zip file')
parser.add_argument('--save-path', type=str, required=True,
help='Output path')
return parser
def extract_1(args):
path = args.path
save_path = args.save_path
# ruleid: tarfile-extractall-traversal
with tarfile.open(path) as f:
f.extractall(save_path)
def extract_2(args):
path = args.path
save_path = args.save_path
# ruleid: tarfile-extractall-traversal
tarfile.open(path).extractall(save_path)
def extract_3(args):
path = args.path
save_path = args.save_path
# ruleid: tarfile-extractall-traversal
tf = tarfile.open(path)
tf.extractall(save_path)
def extract_4(args, tarobj):
# ruleid: tarfile-extractall-traversal
tf = tarfile.open(mode='r', fileobj=None)
tf.extractall(save_path)
def extract_5(args, tarobj):
# ok: tarfile-extractall-traversal
tf = tarfile.open(mode='r', fileobj=None)
tf.extractall(save_path, members=safu_members())
def extract_6(args, tarobj):
# ok: tarfile-extractall-traversal
tf = tarfile.open(mode='r', fileobj=None)
tf.extractall(members=safu_members(), numeric_owner=True, path=save_path)
def extract_7(args, tarobj):
# todoruleid: tarfile-extractall-traversal
tf = tarfile.open(mode='r', fileobj=None)
tf.extractall(members=None, numeric_owner=True, path=save_path)
def run():
parser = get_parser()
args = parser.parse_args()
extract_1(args)
extract_2(args)
extract_3(args)
extract_4(args)
extract_5(args)
extract_6(args)
extract_7(args)
if __name__ == '__main__':
run()
Short Link: https://sg.run/2RLD