def _recordMoatRequest(self, request, success): logging.debug("Moat request has user agent: %s" % request.requestHeaders.getRawHeaders("User-Agent")) ipAddr = getClientIP(request, useForwardedHeader=True, skipLoopback=False) countryCode = resolveCountryCode(ipAddr) try: encodedClientData = request.content.read() clientData = json.loads(encodedClientData)["data"][0] transport = clientData["transport"] bridgeType = "vanilla" if not len(transport) else transport except Exception as err: logging.warning("Could not decode request: %s" % err) return if not isBridgeTypeSupported(bridgeType): logging.warning("User requested unsupported transport type %s " "over moat." % bridgeType) return logging.debug("Recording %svalid moat request for %s from %s (%s)." % ("" if success else "in", bridgeType, ipAddr, countryCode)) # Now update our metrics. key = self.createKey(self.keyPrefix, bridgeType, countryCode, success, self.findAnomaly(request)) self.inc(key)
def test_getClientIP_XForwardedFor(self): """getClientIP() should return the IP address from the 'X-Forwarded-For' header when ``useForwardedHeader=True``. """ request = self.createRequestWithIPs() clientIP = server.getClientIP(request, useForwardedHeader=True) self.assertEqual(clientIP, '2.2.2.2')
def test_getClientIP_fromRequest(self): """getClientIP() should return the IP address from the request instance when ``useForwardedHeader=False``. """ request = self.createRequestWithIPs() clientIP = server.getClientIP(request) self.assertEqual(clientIP, '3.3.3.3')
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
def test_getClientIP_XForwardedFor_bad_ip(self): """getClientIP() should return None if the IP address from the 'X-Forwarded-For' header is bad/invalid and ``useForwardedHeader=True``. """ request = self.createRequestWithIPs() request.headers.update({'x-forwarded-for': 'pineapple'}) clientIP = server.getClientIP(request, useForwardedHeader=True) self.assertEqual(clientIP, None)
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
def getClientIP(self, request): """Get the client's IP address from the ``'X-Forwarded-For:'`` header, or from the :api:`request <twisted.web.server.Request>`. :type request: :api:`twisted.web.http.Request` :param request: A ``Request`` object for a :api:`twisted.web.resource.Resource`. :rtype: ``None`` or :any:`str` :returns: The client's IP address, if it was obtainable. """ return getClientIP(request, self.useForwardedHeader)
def getClientIP(self, request): """Get the client's IP address from the ``'X-Forwarded-For:'`` header, or from the :api:`request <twisted.web.server.Request>`. :type request: :api:`twisted.web.http.Request` :param request: A ``Request`` for a :api:`twisted.web.resource.Resource`. :rtype: ``None`` or :any:`str` :returns: The client's IP address, if it was obtainable. """ return getClientIP(request, self.useForwardedHeader, self.skipLoopback)
def render_POST(self, request): """If we're in debug mode, log a Content Security Policy violation. :type request: :api:`twisted.web.http.Request` :param request: A ``Request`` object for :attr:`reportViolationURI`. """ try: client = getClientIP(request, self.useForwardedHeader) report = request.content.read(2048) logging.warning("Content-Security-Policy violation report from %s: %r" % (client or "UNKNOWN CLIENT", report)) except Exception as err: logging.error("Error while attempting to log CSP report: %s" % err) # Redirect back to the original resource after the report was logged: return redirectTo(request.uri, request)
def render_POST(self, request): """If we're in debug mode, log a Content Security Policy violation. :type request: :api:`twisted.web.http.Request` :param request: A ``Request`` object for :attr:`reportViolationURI`. """ try: client = getClientIP(request, self.useForwardedHeader) report = request.content.read(2048) logging.warning( "Content-Security-Policy violation report from %s: %r" % (client or "UNKNOWN CLIENT", report)) except Exception as err: logging.error("Error while attempting to log CSP report: %s" % err) # Redirect back to the original resource after the report was logged: return redirectTo(request.uri, request)
def _recordHTTPSRequest(self, request, success): logging.debug("HTTPS request has user agent: %s" % request.requestHeaders.getRawHeaders("User-Agent")) # Pull the client's IP address out of the request and convert it to a # two-letter country code. ipAddr = getClientIP(request, useForwardedHeader=True, skipLoopback=False) self.updateSubnetCounter(ipAddr) countryCode = resolveCountryCode(ipAddr) transports = request.args.get("transport", list()) if len(transports) > 1: logging.warning("Expected a maximum of one transport but %d are " "given." % len(transports)) if len(transports) == 0: bridgeType = "vanilla" elif transports[0] == "" or transports[0] == "0": bridgeType = "vanilla" else: bridgeType = transports[0] # BridgeDB's HTTPS interface exposes transport types as a drop down # menu but users can still request anything by manipulating HTTP # parameters. if not isBridgeTypeSupported(bridgeType): logging.warning("User requested unsupported transport type %s " "over HTTPS." % bridgeType) return logging.debug("Recording %svalid HTTPS request for %s from %s (%s)." % ("" if success else "in", bridgeType, ipAddr, countryCode)) # Now update our metrics. key = self.createKey(self.keyPrefix, bridgeType, countryCode, success, self.findAnomaly(request)) self.inc(key)
def test_getClientIP_XForwardedFor_skip_loopback_multiple(self): request = self.createRequestWithIPs() request.headers.update({'x-forwarded-for': '3.3.3.3, 127.0.0.6, 127.0.0.1'}) clientIP = server.getClientIP(request, useForwardedHeader=True, skipLoopback=True) self.assertEqual(clientIP, '3.3.3.3')