Add template for 403 CSRF Bad Origin failure

This commit is contained in:
Christopher C. Wells 2022-02-21 21:26:12 -08:00 committed by Christopher Charbonneau Wells
parent a145d4dffa
commit b1ee9fe043
4 changed files with 58 additions and 0 deletions

View File

@ -243,6 +243,7 @@ SESSION_COOKIE_HTTPONLY = True
# https://docs.djangoproject.com/en/4.0/ref/csrf/#settings # https://docs.djangoproject.com/en/4.0/ref/csrf/#settings
CSRF_COOKIE_HTTPONLY = True CSRF_COOKIE_HTTPONLY = True
# CSRF_COOKIE_SECURE = True # CSRF_COOKIE_SECURE = True
CSRF_FAILURE_VIEW = "babybuddy.views.csrf_failure"
CSRF_TRUSTED_ORIGINS = list( CSRF_TRUSTED_ORIGINS = list(
filter(None, os.environ.get("CSRF_TRUSTED_ORIGINS", "").split(",")) filter(None, os.environ.get("CSRF_TRUSTED_ORIGINS", "").split(","))
) )

View File

@ -0,0 +1,29 @@
{% extends 'babybuddy/base.html' %}
{% load i18n widget_tweaks %}
{% block title %}403 {{ title }}{% endblock %}
{% block breadcrumb_nav %}{% endblock %}
{% block page %}
<div class="container mt-2 mt-lg-5">
<div class="row justify-content-md-center">
<div class="col-lg-12 mb-4">
<div>
<h1>403: {{ title }}</h1>
<div class="alert alert-danger" role="alert">
{{ main }} {{ reason }}
</div>
<div class="jumbotron">
<h2>{% trans "How to Fix" %}</h2>
{% blocktrans trimmed with origin=origin %}
Add <samp>{{ origin }}</samp> to the <code>CSRF_TRUSTED_ORIGINS</code>
environment variable. If multiple origins are required separate
with commas.
{% endblocktrans %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -5,12 +5,16 @@ from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.views import LogoutView as LogoutViewBase from django.contrib.auth.views import LogoutView as LogoutViewBase
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.http import HttpResponseForbidden
from django.middleware.csrf import REASON_BAD_ORIGIN
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.template import loader, TemplateDoesNotExist
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils import translation from django.utils import translation
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.text import format_lazy from django.utils.text import format_lazy
from django.utils.translation import gettext as _, gettext_lazy from django.utils.translation import gettext as _, gettext_lazy
from django.views import csrf
from django.views.decorators.cache import never_cache from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect from django.views.decorators.csrf import csrf_protect
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
@ -25,6 +29,30 @@ from babybuddy import forms
from babybuddy.mixins import LoginRequiredMixin, PermissionRequiredMixin, StaffOnlyMixin from babybuddy.mixins import LoginRequiredMixin, PermissionRequiredMixin, StaffOnlyMixin
def csrf_failure(request, reason=""):
"""
Overrides the 403 CSRF failure template for bad origins in order to provide more
userful information about how to resolve the issue.
"""
if (
"HTTP_ORIGIN" in request.META
and reason == REASON_BAD_ORIGIN % request.META["HTTP_ORIGIN"]
):
c = {
"title": _("Forbidden"),
"main": _("CSRF verification failed. Request aborted."),
"reason": reason,
"origin": request.META["HTTP_ORIGIN"],
}
try:
t = loader.get_template("error/403_csrf_bad_origin.html")
return HttpResponseForbidden(t.render(c), content_type="text/html")
except TemplateDoesNotExist:
pass
return csrf.csrf_failure(request, reason, "403_csrf.html")
class RootRouter(LoginRequiredMixin, RedirectView): class RootRouter(LoginRequiredMixin, RedirectView):
""" """
Redirects to the site dashboard. Redirects to the site dashboard.