From: Michael Tremer Date: Tue, 6 Nov 2018 09:57:18 +0000 (+0000) Subject: Add decorator to check if request is coming from a blacklisted host X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cfe7d74c91a54cd78a25188b1d0701cda4d1cee9;p=ipfire.org.git Add decorator to check if request is coming from a blacklisted host Signed-off-by: Michael Tremer --- diff --git a/src/backend/geoip.py b/src/backend/geoip.py index fe28c480..564cf403 100644 --- a/src/backend/geoip.py +++ b/src/backend/geoip.py @@ -259,11 +259,15 @@ class Address(Object): # Not found if not res: + logging.debug("%s is not blacklisted on %s" % (self, blacklist)) return False, None # If the IP address is on a blacklist, we will try to fetch the TXT record reason = yield self.backend.geoip.resolver.query(rr, type=pycares.QUERY_TYPE_TXT) + # Log result + logging.debug("%s is blacklisted on %s: %s" % (self, blacklist, reason or "N/A")) + # Take the first reason if reason: for i in reason: @@ -280,6 +284,9 @@ class Address(Object): @tornado.gen.coroutine def is_blacklisted(self): + logging.debug("Checking if %s is blacklisted..." % self) + + # Perform checks blacklists = yield self.get_blacklists(important_only=True) # If we are blacklisted on one list, this one is screwed diff --git a/src/web/auth.py b/src/web/auth.py index bf481d97..82e6f0d8 100644 --- a/src/web/auth.py +++ b/src/web/auth.py @@ -39,11 +39,13 @@ class AuthenticationMixin(object): class LoginHandler(AuthenticationMixin, base.BaseHandler): + @base.blacklisted def get(self): next = self.get_argument("next", None) self.render("auth/login.html", next=next) + @base.blacklisted def post(self): username = self.get_argument("username") password = self.get_argument("password") diff --git a/src/web/base.py b/src/web/base.py index b6fee9b5..4c1b3a9e 100644 --- a/src/web/base.py +++ b/src/web/base.py @@ -2,6 +2,7 @@ import datetime import dateutil.parser +import functools import http.client import ipaddress import logging @@ -12,6 +13,24 @@ import tornado.web from ..decorators import * from .. import util +def blacklisted(method): + @tornado.gen.coroutine + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + # Check if remote is blacklisted + is_blacklisted = yield self.remote.is_blacklisted() + + # If so, redirect to the blocked page + if is_blacklisted: + logging.warning("%s is blacklisted" % self.remote) + + return self.redirect("https://www.ipfire.org/blocked") + + return method(self, *args, **kwargs) + + return wrapper + + class BaseHandler(tornado.web.RequestHandler): def set_expires(self, seconds): # For HTTP/1.1 @@ -78,6 +97,13 @@ class BaseHandler(tornado.web.RequestHandler): # Return the last IP if nothing else worked return remote_ips.pop() + @lazy_property + def remote(self): + address = self.get_remote_ip() + + if address: + return self.backend.geoip.lookup(address) + @lazy_property def current_country_code(self): remote_ip = self.get_remote_ip() diff --git a/src/web/blog.py b/src/web/blog.py index 375adfc3..70349f6f 100644 --- a/src/web/blog.py +++ b/src/web/blog.py @@ -119,6 +119,7 @@ class DraftsHandler(auth.CacheMixin, base.BaseHandler): class SearchHandler(auth.CacheMixin, base.BaseHandler): + @base.blacklisted def get(self): q = self.get_argument("q") diff --git a/src/web/download.py b/src/web/download.py index 2e588c4b..aaaebbf4 100644 --- a/src/web/download.py +++ b/src/web/download.py @@ -34,6 +34,7 @@ class FileHandler(base.BaseHandler): def prepare(self): self.set_header("Pragma", "no-cache") + @base.blacklisted def get(self, filename): mirror = self.backend.mirrors.get_for_download(filename, country_code=self.current_country_code) diff --git a/src/web/newsletter.py b/src/web/newsletter.py index 49b9ca7f..12909ade 100644 --- a/src/web/newsletter.py +++ b/src/web/newsletter.py @@ -9,6 +9,7 @@ from . import base class SubscribeHandler(base.BaseHandler): @tornado.gen.coroutine + @base.blacklisted def post(self): address = self.get_argument("email") diff --git a/src/web/nopaste.py b/src/web/nopaste.py index 8a7784ef..2b37fe32 100644 --- a/src/web/nopaste.py +++ b/src/web/nopaste.py @@ -9,6 +9,7 @@ from . import ui_modules class CreateHandler(base.BaseHandler): MODES = ("paste", "upload") + @base.blacklisted def get(self): mode = self.get_argument("mode", "paste") if not mode in self.MODES: @@ -17,6 +18,7 @@ class CreateHandler(base.BaseHandler): self.render("nopaste/create.html", mode=mode, max_size=self._max_size) + @base.blacklisted def post(self): mode = self.get_argument("mode") if not mode in self.MODES: @@ -65,6 +67,7 @@ class CreateHandler(base.BaseHandler): class RawHandler(base.BaseHandler): + @base.blacklisted def get(self, uid): entry = self.backend.nopaste.get(uid) if not entry: @@ -85,6 +88,7 @@ class RawHandler(base.BaseHandler): class ViewHandler(auth.CacheMixin, base.BaseHandler): + @base.blacklisted def get(self, uid): entry = self.backend.nopaste.get(uid) if not entry: