1111
1212
1313# 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
1718
1819# 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="/"
2122
2223# 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"
2425
2526# low level sending of request
26- conn .putrequest ("GET" , "url" ) # $ MISSING: clientRequestUrl="url"
27+ conn .putrequest ("GET" , "url" ) # $ clientRequestUrl="url"
2728conn .putheader ("X-Foo" , "value" )
2829conn .endheaders (message_body = None )
2930
3031# 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"
3334
3435# six aliases
3536import six
3637
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"
3940
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"
4243
4344# ==============================================================================
4445# Certificate validation disabled
4950assert context .check_hostname == True
5051assert context .verify_mode == ssl .CERT_REQUIRED
5152
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"
5455
5556# `_create_default_https_context` is currently just an alias for `create_default_context`
5657# which creates a context for SERVER_AUTH purpose.
5758context = ssl .create_default_context ()
5859assert context .check_hostname == True
5960assert context .verify_mode == ssl .CERT_REQUIRED
6061
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"
6364
6465# however, if you supply your own SSLContext, you need to set it manually
6566context = ssl .SSLContext ()
6667assert context .check_hostname == False
6768assert context .verify_mode == ssl .CERT_NONE
6869
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
7172
7273# and if you misunderstood whether to use server/client in the purpose, you will also
7374# get a context without hostname verification.
7475context = ssl .create_default_context (ssl .Purpose .CLIENT_AUTH )
7576assert context .check_hostname == False
7677assert context .verify_mode == ssl .CERT_NONE
7778
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
8081
8182# NOTICE that current documentation says
8283#
8990context .check_hostname = True
9091assert context .verify_mode == ssl .CERT_REQUIRED
9192
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"
9495
9596# only setting verify_mode is not enough, since check_hostname is not enabled
9697
9798context = ssl .SSLContext ()
9899context .verify_mode = ssl .CERT_REQUIRED
99100assert context .check_hostname == False
100101
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
103104
104105# ==============================================================================
105106# taint test
@@ -111,8 +112,8 @@ def taint_test():
111112 host = request .args ['host' ]
112113 url = request .args ['url' ]
113114
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
116117
117118 resp = conn .getresponse ()
118119
@@ -122,37 +123,48 @@ def taint_test():
122123 # https://docs.python.org/3/library/http.client.html#http.client.HTTPResponse
123124
124125 # a HTTPResponse itself is file-like
125- resp , # $ MISSING: tainted
126- resp .read (), # $ MISSING: tainted
126+ resp , # $ tainted
127+ resp .read (), # $ tainted
127128
128- resp .getheader ("name" ), # $ MISSING: tainted
129- resp .getheaders (), # $ MISSING: tainted
129+ resp .getheader ("name" ), # $ tainted
130+ resp .getheaders (), # $ tainted
130131
131132 # 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
134135
135136 # Alias for .headers
136137 # 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
139140
140141 # 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
143144
144145 # although this would usually be the textual version of the status
145146 # ("OK" for 200), it is possible to put your own evil data in here.
146- resp .reason , # $ MISSING: tainted
147+ resp .reason , # $ tainted
147148
148149 # the URL of the recourse that was visited, if redirects were followed.
149150 # 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
152153 )
153154
154155 ensure_not_tainted (
155156 resp .status ,
156157 resp .code ,
157158 resp .getcode (),
158159 )
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