From 8d653e3059b3225a3251c25eb4a65f23db5df160 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 15 Oct 2015 01:09:57 -0400 Subject: [PATCH 1/2] adding test for leaking auth url keys --- nbviewer/tests/test_security.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nbviewer/tests/test_security.py b/nbviewer/tests/test_security.py index 4c1d6c3a..6629cac4 100644 --- a/nbviewer/tests/test_security.py +++ b/nbviewer/tests/test_security.py @@ -35,3 +35,14 @@ def test_url(self): url = self.url('localfile/../README.md') r = requests.get(url) self.assertEqual(r.status_code, 404) + + +class URLLeakTestCase(NBViewerTestCase): + def test_gist(self): + url = self.url('/github/jupyter') + r = requests.get(url) + self.assertEqual(r.status_code, 200) + html = r.content + self.assertNotIn('client_id', html) + self.assertNotIn('client_secret', html) + self.assertNotIn('access_token', html) \ No newline at end of file From b5253f4fae27da2a07e74cb953b8ebea83041e71 Mon Sep 17 00:00:00 2001 From: Nicholas Bollweg Date: Thu, 15 Oct 2015 01:10:15 -0400 Subject: [PATCH 2/2] adding key stripping for github auth --- nbviewer/utils.py | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/nbviewer/utils.py b/nbviewer/utils.py index c9c2d136..856c27ea 100644 --- a/nbviewer/utils.py +++ b/nbviewer/utils.py @@ -11,13 +11,33 @@ from subprocess import check_output try: - from urllib.parse import quote as stdlib_quote + from urllib.parse import ( + parse_qs, + quote as stdlib_quote, + urlencode, + urlparse, + urlunparse, + ) except ImportError: + from urllib import urlencode from urllib2 import quote as stdlib_quote + from urlparse import ( + parse_qs, + urlparse, + urlunparse, + ) + from IPython.utils import py3compat +STRIP_PARAMS = [ + 'client_id', + 'client_secret', + 'access_token', +] + + def quote(s): """unicode-safe quote @@ -113,11 +133,11 @@ def response_text(response, encoding=None): # parse_header_links from requests.util # modified to actually return a dict, like the docstring says. + def parse_header_links(value): """Return a dict of parsed link headers proxies. i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg" - """ links = {} @@ -132,7 +152,19 @@ def parse_header_links(value): link = {} - link["url"] = url.strip("<> '\"") + parts = list(urlparse(url.strip("<> '\""))) + + get_params = parse_qs(parts[4]) + + get_params = { + key: value[0] + for key, value in get_params.items() + if key not in STRIP_PARAMS + } + parts[4] = urlencode(get_params) + + link["url"] = urlunparse(parts) + for param in params.split(";"): try: key, value = param.split("=") @@ -146,6 +178,7 @@ def parse_header_links(value): return links + def git_info(path): """Return some git info""" command = ['git', 'log', '-1', '--format=%H\n%s\n%cD']