django-csp/csp/contrib/rate_limiting.py

43 строки
1.5 KiB
Python

from __future__ import annotations
import random
from typing import TYPE_CHECKING
from django.conf import settings
from csp.middleware import CSPMiddleware, PolicyParts
if TYPE_CHECKING:
from django.http import HttpRequest, HttpResponseBase
class RateLimitedCSPMiddleware(CSPMiddleware):
"""A CSP middleware that rate-limits the number of violation reports sent
to report-uri by excluding it from some requests."""
def get_policy_parts(self, request: HttpRequest, response: HttpResponseBase, report_only: bool = False) -> PolicyParts:
policy_parts = super().get_policy_parts(request, response, report_only)
csp_setting_name = "CONTENT_SECURITY_POLICY_REPORT_ONLY" if report_only else "CONTENT_SECURITY_POLICY"
policy = getattr(settings, csp_setting_name, None)
if policy is None:
return policy_parts
# `random.random` returns a value in the range [0.0, 1.0) so all values will be < 100.0.
remove_report = random.random() * 100 >= policy.get("REPORT_PERCENTAGE", 100)
if remove_report:
if policy_parts.replace is None:
policy_parts.replace = {
"report-uri": None,
"report-to": None,
}
else:
policy_parts.replace.update(
{
"report-uri": None,
"report-to": None,
}
)
return policy_parts