11
11
12
12
13
13
# NOTE: the URL may be relative to host, or may be full URL.
14
- conn = HTTPConnection ("example.com" ) # $ MISSING: clientRequestUrl="example.com"
15
- conn .request ("GET" , "/" ) # $ MISSING: clientRequestUrl="/"
16
- conn .request ("GET" , "http://example.com/" ) # $ MISSING: clientRequestUrl="http://example.com/"
14
+ conn = HTTPConnection ("example.com" ) # $ clientRequestUrl="example.com"
15
+ conn .request ("GET" , "/" ) # $ clientRequestUrl="/"
16
+ url = "http://example.com/"
17
+ conn .request ("GET" , url ) # $ clientRequestUrl=url
17
18
18
19
# kwargs
19
- conn = HTTPConnection (host = "example.com" ) # $ MISSING: clientRequestUrl="example.com"
20
- conn .request (method = "GET" , url = "/" ) # $ MISSING: clientRequestUrl="/"
20
+ conn = HTTPConnection (host = "example.com" ) # $ clientRequestUrl="example.com"
21
+ conn .request (method = "GET" , url = "/" ) # $ clientRequestUrl="/"
21
22
22
23
# using internal method... you shouldn't but you can
23
- conn ._send_request ("GET" , "url" , body = None , headers = {}, encode_chunked = False ) # $ MISSING: clientRequestUrl="url"
24
+ conn ._send_request ("GET" , "url" , body = None , headers = {}, encode_chunked = False ) # $ clientRequestUrl="url"
24
25
25
26
# low level sending of request
26
- conn .putrequest ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
27
+ conn .putrequest ("GET" , "url" ) # $ clientRequestUrl="url"
27
28
conn .putheader ("X-Foo" , "value" )
28
29
conn .endheaders (message_body = None )
29
30
30
31
# HTTPS
31
- conn = HTTPSConnection ("host" ) # $ MISSING: clientRequestUrl="host"
32
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
32
+ conn = HTTPSConnection ("host" ) # $ clientRequestUrl="host"
33
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url"
33
34
34
35
# six aliases
35
36
import six
36
37
37
- conn = six .moves .http_client .HTTPConnection ("host" ) # $ MISSING: clientRequestUrl="host"
38
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
38
+ conn = six .moves .http_client .HTTPConnection ("host" ) # $ clientRequestUrl="host"
39
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url"
39
40
40
- conn = six .moves .http_client .HTTPSConnection ("host" ) # $ MISSING: clientRequestUrl="host"
41
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
41
+ conn = six .moves .http_client .HTTPSConnection ("host" ) # $ clientRequestUrl="host"
42
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url"
42
43
43
44
# ==============================================================================
44
45
# Certificate validation disabled
49
50
assert context .check_hostname == True
50
51
assert context .verify_mode == ssl .CERT_REQUIRED
51
52
52
- conn = HTTPSConnection ("host" , context = context ) # $ MISSING: clientRequestUrl="host"
53
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
53
+ conn = HTTPSConnection ("host" , context = context ) # $ clientRequestUrl="host"
54
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url"
54
55
55
56
# `_create_default_https_context` is currently just an alias for `create_default_context`
56
57
# which creates a context for SERVER_AUTH purpose.
57
58
context = ssl .create_default_context ()
58
59
assert context .check_hostname == True
59
60
assert context .verify_mode == ssl .CERT_REQUIRED
60
61
61
- conn = HTTPSConnection ("host" , context = context ) # $ MISSING: clientRequestUrl="host"
62
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
62
+ conn = HTTPSConnection ("host" , context = context ) # $ clientRequestUrl="host"
63
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url"
63
64
64
65
# however, if you supply your own SSLContext, you need to set it manually
65
66
context = ssl .SSLContext ()
66
67
assert context .check_hostname == False
67
68
assert context .verify_mode == ssl .CERT_NONE
68
69
69
- conn = HTTPSConnection ("host" , context = context ) # $ MISSING: clientRequestUrl="host"
70
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url" clientRequestCertValidationDisabled
70
+ conn = HTTPSConnection ("host" , context = context ) # $ clientRequestUrl="host"
71
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url" MISSING: clientRequestCertValidationDisabled
71
72
72
73
# and if you misunderstood whether to use server/client in the purpose, you will also
73
74
# get a context without hostname verification.
74
75
context = ssl .create_default_context (ssl .Purpose .CLIENT_AUTH )
75
76
assert context .check_hostname == False
76
77
assert context .verify_mode == ssl .CERT_NONE
77
78
78
- conn = HTTPSConnection ("host" , context = context ) # $ MISSING: clientRequestUrl="host"
79
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url" clientRequestCertValidationDisabled
79
+ conn = HTTPSConnection ("host" , context = context ) # $ clientRequestUrl="host"
80
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url" MISSING: clientRequestCertValidationDisabled
80
81
81
82
# NOTICE that current documentation says
82
83
#
89
90
context .check_hostname = True
90
91
assert context .verify_mode == ssl .CERT_REQUIRED
91
92
92
- conn = HTTPSConnection ("host" , context = context ) # $ MISSING: clientRequestUrl="host"
93
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
93
+ conn = HTTPSConnection ("host" , context = context ) # $ clientRequestUrl="host"
94
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url"
94
95
95
96
# only setting verify_mode is not enough, since check_hostname is not enabled
96
97
97
98
context = ssl .SSLContext ()
98
99
context .verify_mode = ssl .CERT_REQUIRED
99
100
assert context .check_hostname == False
100
101
101
- conn = HTTPSConnection ("host" , context = context ) # $ MISSING: clientRequestUrl="host"
102
- conn .request ("GET" , "url" ) # $ MISSING: clientRequestUrl="url" clientRequestCertValidationDisabled
102
+ conn = HTTPSConnection ("host" , context = context ) # $ clientRequestUrl="host"
103
+ conn .request ("GET" , "url" ) # $ clientRequestUrl="url" MISSING: clientRequestCertValidationDisabled
103
104
104
105
# ==============================================================================
105
106
# taint test
@@ -111,8 +112,8 @@ def taint_test():
111
112
host = request .args ['host' ]
112
113
url = request .args ['url' ]
113
114
114
- conn = HTTPConnection (host ) # $ MISSING: clientRequestUrl=host
115
- conn .request ("GET" , url ) # $ MISSING: clientRequestUrl=url
115
+ conn = HTTPConnection (host ) # $ clientRequestUrl=host
116
+ conn .request ("GET" , url ) # $ clientRequestUrl=url
116
117
117
118
resp = conn .getresponse ()
118
119
@@ -122,37 +123,48 @@ def taint_test():
122
123
# https://docs.python.org/3/library/http.client.html#http.client.HTTPResponse
123
124
124
125
# a HTTPResponse itself is file-like
125
- resp , # $ MISSING: tainted
126
- resp .read (), # $ MISSING: tainted
126
+ resp , # $ tainted
127
+ resp .read (), # $ tainted
127
128
128
- resp .getheader ("name" ), # $ MISSING: tainted
129
- resp .getheaders (), # $ MISSING: tainted
129
+ resp .getheader ("name" ), # $ tainted
130
+ resp .getheaders (), # $ tainted
130
131
131
132
# http.client.HTTPMessage
132
- resp .headers , # $ MISSING: tainted
133
- resp .headers .get_all (), # $ MISSING: tainted
133
+ resp .headers , # $ tainted
134
+ resp .headers .get_all (), # $ tainted
134
135
135
136
# Alias for .headers
136
137
# http.client.HTTPMessage
137
- resp .msg , # $ MISSING: tainted
138
- resp .msg .get_all (), # $ MISSING: tainted
138
+ resp .msg , # $ tainted
139
+ resp .msg .get_all (), # $ tainted
139
140
140
141
# Alias for .headers
141
- resp .info (), # $ MISSING: tainted
142
- resp .info ().get_all (), # $ MISSING: tainted
142
+ resp .info (), # $ tainted
143
+ resp .info ().get_all (), # $ tainted
143
144
144
145
# although this would usually be the textual version of the status
145
146
# ("OK" for 200), it is possible to put your own evil data in here.
146
- resp .reason , # $ MISSING: tainted
147
+ resp .reason , # $ tainted
147
148
148
149
# the URL of the recourse that was visited, if redirects were followed.
149
150
# I don't see any reason this could not contain evil data.
150
- resp .url , # $ MISSING: tainted
151
- resp .geturl (), # $ MISSING: tainted
151
+ resp .url , # $ tainted
152
+ resp .geturl (), # $ tainted
152
153
)
153
154
154
155
ensure_not_tainted (
155
156
resp .status ,
156
157
resp .code ,
157
158
resp .getcode (),
158
159
)
160
+
161
+ # check that only setting either host/url is enough to propagate taint
162
+ conn = HTTPConnection ("host" ) # $ clientRequestUrlPart="host"
163
+ conn .request ("GET" , url ) # $ clientRequestUrlPart=url
164
+ resp = conn .getresponse ()
165
+ ensure_tainted (resp ) # $ tainted
166
+
167
+ conn = HTTPConnection (host ) # $ clientRequestUrlPart=host
168
+ conn .request ("GET" , "url" ) # $ clientRequestUrlPart="url"
169
+ resp = conn .getresponse ()
170
+ ensure_tainted (resp ) # $ tainted
0 commit comments