-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathtarslip.py
More file actions
116 lines (86 loc) · 2.98 KB
/
tarslip.py
File metadata and controls
116 lines (86 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/python
import tarfile
import os
import sys
unsafe_filename_tar = sys.argv[1]
safe_filename_tar = "safe_path.tar"
tar = tarfile.open(safe_filename_tar)
for entry in tar:
tar.extract(entry)
tar = tarfile.open(unsafe_filename_tar)
tar.extractall()
tar.close()
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
tar.extract(entry)
tar = tarfile.open(safe_filename_tar)
tar.extractall()
tar.close()
#Sanitized
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
if os.path.isabs(entry.name) or ".." in entry.name:
raise ValueError("Illegal tar archive entry")
tar.extract(entry, "/tmp/unpack/")
#Part Sanitized
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
if ".." in entry.name:
raise ValueError("Illegal tar archive entry")
tar.extract(entry, "/tmp/unpack/")
#Unsanitized members
tar = tarfile.open(unsafe_filename_tar)
tar.extractall(members=tar)
#Sanitize members
def safemembers(members):
for info in members:
if badpath(info):
raise
yield info
tar = tarfile.open(unsafe_filename_tar)
tar.extractall(members=safemembers(tar))
# Wrong sanitizer (is missing not)
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
if os.path.isabs(entry.name) or ".." in entry.name:
tar.extract(entry, "/tmp/unpack/")
# OK Sanitized using not
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
if not (os.path.isabs(entry.name) or ".." in entry.name):
tar.extract(entry, "/tmp/unpack/")
# The following two variants are included by purpose, since by default there is a
# difference in handling `not x` and `not (x or False)` when overriding
# Sanitizer.sanitizingEdge. We want to ensure we handle both consistently.
# Not reported, although vulnerable to '..'
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
if not (os.path.isabs(entry.name) or False):
tar.extract(entry, "/tmp/unpack/")
# Not reported, although vulnerable to '..'
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
if not os.path.isabs(entry.name):
tar.extract(entry, "/tmp/unpack/")
# Extraction filters
extraction_filter = "fully_trusted"
tar = tarfile.open(unsafe_filename_tar)
tar.extractall(filter=extraction_filter) # unsafe
tar.close()
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
tar.extract(entry, filter=extraction_filter) # unsafe
extraction_filter = "data"
tar = tarfile.open(unsafe_filename_tar)
tar.extractall(filter=extraction_filter) # safe
tar.close()
tar = tarfile.open(unsafe_filename_tar)
for entry in tar:
tar.extract(entry, filter=extraction_filter) # safe
extraction_filter = None
tar = tarfile.open(unsafe_filename_tar)
tar.extractall(filter=extraction_filter) # unsafe
tar = tarfile.open(unsafe_filename_tar)
tar.extractall(members=tar, filter=extraction_filter) # unsafe
tar = tarfile.open(unsafe_filename_tar)
tar.extractall(members=safemembers(tar), filter=extraction_filter) # safe -- we assume `safemembers` makes up for the unsafe filter