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
CSRF_COOKIE_HTTPONLY = True
# CSRF_COOKIE_SECURE = True
CSRF_FAILURE_VIEW = "babybuddy.views.csrf_failure"
CSRF_TRUSTED_ORIGINS = list(
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.views import LogoutView as LogoutViewBase
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.template import loader, TemplateDoesNotExist
from django.urls import reverse, reverse_lazy
from django.utils import translation
from django.utils.decorators import method_decorator
from django.utils.text import format_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.csrf import csrf_protect
from django.views.decorators.http import require_POST
@ -25,6 +29,30 @@ from babybuddy import forms
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):
"""
Redirects to the site dashboard.