Source code for duck.http.middlewares.security.url

"""
Module containing middleware classes for inspecting URLs for various attacks like XSS and SQL Injection.
"""

from duck.http.middlewares import BaseMiddleware
from duck.http.middlewares.security.modules.command_injection import check_command_injection_in_url
from duck.http.middlewares.security.modules.sql_injection import check_sql_injection_in_url
from duck.http.middlewares.security.modules.xss import check_xss_in_url
from duck.http.response import HttpBadRequestResponse
from duck.utils.path import is_good_url_path
from duck.settings import SETTINGS


[docs] class URLSecurityMiddleware(BaseMiddleware): """ URLSecurityMiddleware class checking URL correctness. """ debug_message: str = "URL Security Middleware: Malformed URL"
[docs] @classmethod def get_error_response(cls, request) -> HttpBadRequestResponse: """ Returns an appropriate response upon error. """ from duck.contrib.responses import make_response body = None if SETTINGS["DEBUG"]: # Add extra debug message in DEBUG body = "<p>URL is Invalid or Malformed.</p>" # Construct and return the final response. response = make_response(HttpBadRequestResponse, body=body) return response
[docs] @classmethod def process_request(cls, request): """ Process basic URL checks on the request. """ url_path_ok = is_good_url_path(request.path) if url_path_ok: return cls.request_ok # URL is malformed at this point return cls.request_bad
[docs] class XSSMiddleware(BaseMiddleware): """ XSSMiddleware class mitigating against XSS attacks. """ debug_message: str = "XSS Middleware: Potential URL XSS"
[docs] @classmethod def get_error_response(cls, request) -> HttpBadRequestResponse: """ Returns appropriate error response. """ from duck.contrib.responses import make_response body = None if SETTINGS["DEBUG"]: body = "<p>URL contains Potential XSS Attack Signature.</p>" url_xss_attack = getattr(request, "url_xss_attack", None) if url_xss_attack: body = f"<p>{url_xss_attack}</p>" # Build and return final response. response = make_response(HttpBadRequestResponse, body=body) return response
[docs] @classmethod def process_request(cls, request): """ Process and check for URL XSS in request. """ url = request.fullpath xss_found, msg = check_xss_in_url(url) if xss_found: request.url_xss_attack = msg return cls.request_bad # Request URL is probably fine. return cls.request_ok
[docs] class SQLInjectionMiddleware(BaseMiddleware): """ SQLInjectionMiddleware class mitigating against SQL injection attacks. """ debug_message: str = "SQL Injection Middleware: Potential URL SQL injection"
[docs] @classmethod def get_error_response(cls, request) -> HttpBadRequestResponse: """ Returns appropriate error response. """ from duck.contrib.responses import make_response body = None if SETTINGS["DEBUG"]: # Add extra debug message. body = "<p>URL contains Potential SQL Injection.</p>" # Build final response. response = make_response(HttpBadRequestResponse, body=body) return response
[docs] @classmethod def process_request(cls, request): """ Check for SQL injection in request's URL """ url = request.fullpath if not check_sql_injection_in_url(url): return cls.request_ok # Request is not safe. return cls.request_bad
[docs] class CommandInjectionMiddleware(BaseMiddleware): """ CommandInjectionMiddleware class mitigating against command injection attacks. """ debug_message = "Command Injection Middleware: Potential URL command injection"
[docs] @classmethod def get_error_response(cls, request) -> HttpBadRequestResponse: """ Returns appropriate error response. """ from duck.contrib.responses import make_response body = None if SETTINGS["DEBUG"]: body = "<p>URL contains Potential Command Injection.</p>" # Build and return final response response = make_response(HttpBadRequestResponse, body=body) return response
[docs] @classmethod def process_request(cls, request): """ Check request's URL for potential command injection. """ # Don't use request.path but request.fullpath (this is better for finding command inj) url = request.fullpath target_1 = url.split("?", 1)[0] # Removing all queries target_2 = url.replace("&", "") # Replace all & if not check_command_injection_in_url(target_1) and not check_command_injection_in_url(target_2): return cls.request_ok # Request potentially unsafe. return cls.request_bad