Skip to content

Commit

Permalink
Merge branch 'fix/24701' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
isislovecruft committed Dec 22, 2017
2 parents 637e1fc + 0f03fb6 commit c6c9f47
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 15 deletions.
43 changes: 34 additions & 9 deletions bridgedb/distributors/https/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
from mako.template import Template
from mako.lookup import TemplateLookup

from twisted.internet import defer
from twisted.internet import reactor
from twisted.internet import task
from twisted.internet.error import CannotListenError
from twisted.web import resource
from twisted.web import static
Expand Down Expand Up @@ -138,6 +140,20 @@ def replaceErrorPage(request, error, template_name=None, html=True):
return rendered


def redirectMaliciousRequest(request):
'''Redirect the client to a "daring work of art" which "in true
post-modern form, […] tends to raise more questions than answers."
'''
logging.debug("Redirecting %s to a daring work of art..." % getClientIP(request))
request.write(redirectTo(base64.b64decode("aHR0cDovLzJnaXJsczFjdXAuY2Ev"), request))
request.finish()
return request


class MaliciousRequest(Exception):
"""Raised when we received a possibly malicious request."""


class CSPResource(resource.Resource):
"""A resource which adds a ``'Content-Security-Policy:'`` header.
Expand Down Expand Up @@ -411,9 +427,9 @@ def extractClientSolution(self, request):
challenge = request.args['captcha_challenge_field'][0]
response = request.args['captcha_response_field'][0]
except Exception as error:
logging.debug(("Client CAPTCHA solution to HTTPS distributor server"
"didn't include correct HTTP arguments: %s" % error))
return redirectTo(type(b'')(request.URLPath()), request)
raise MaliciousRequest(
("Client CAPTCHA solution to HTTPS distributor server "
"didn't include correct HTTP arguments: %s" % error))
return (challenge, response)

def checkSolution(self, request):
Expand Down Expand Up @@ -477,12 +493,21 @@ def render_POST(self, request):
self.setCSPHeader(request)
request.setHeader("Content-Type", "text/html; charset=utf-8")

if self.checkSolution(request) is True:
try:
rendered = self.resource.render(request)
except Exception as err:
rendered = replaceErrorPage(request, err)
return rendered
try:
if self.checkSolution(request) is True:
return self.resource.render(request)
except ValueError as err:
logging.debug(err.message)
except MaliciousRequest as err:
logging.debug(err.message)
# Make them wait a bit, then redirect them to a "daring
# work of art" as pennance for their sins.
d = task.deferLater(reactor, 1, lambda: request)
d.addCallback(redirectMaliciousRequest)
return NOT_DONE_YET
except Exception as err:
logging.debug(err.message)
return replaceErrorPage(request, err)

logging.debug("Client failed a CAPTCHA; returning redirect to %s"
% request.uri)
Expand Down
11 changes: 5 additions & 6 deletions bridgedb/test/test_https_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,18 +373,17 @@ def test_extractClientSolution(self):
self.assertEqual(response, expectedResponse)

def test_extractClientSolution_missing_arguments(self):
"""A solution with missing arguments (the solution field) should
return a very agressive redirect to the originally requested,
CAPTCHA-protected page.
"""A solution with missing arguments (the solution/challenge fields)
should raise a MaliciousRequest exception.
"""
expectedChallenge = '23232323232323232323'

self.request.method = b'POST'
self.request.addArg('captcha_challenge_field', expectedChallenge)

response = self.captchaResource.extractClientSolution(self.request)

self.assertIn("click here", response)
self.assertRaises(server.MaliciousRequest,
self.captchaResource.extractClientSolution,
self.request)

def test_checkSolution(self):
"""checkSolution() should return False is the solution is invalid."""
Expand Down

0 comments on commit c6c9f47

Please sign in to comment.