From a41c9eeb85d392af08af19e496b7d73368e57644 Mon Sep 17 00:00:00 2001 From: Fredrik Jonsson Date: Wed, 13 May 2026 11:49:17 +0200 Subject: [PATCH 1/4] Partials for lead and meta tags lacked permission checks. --- hypha/apply/funds/views/partials.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hypha/apply/funds/views/partials.py b/hypha/apply/funds/views/partials.py index 2fedeb72ad..69ffe746f0 100644 --- a/hypha/apply/funds/views/partials.py +++ b/hypha/apply/funds/views/partials.py @@ -50,6 +50,9 @@ @login_required def partial_submission_lead(request, pk): submission = get_object_or_404(ApplicationSubmission, pk=pk) + has_permission( + "submission_view", request.user, object=submission, raise_exception=True + ) return render( request, "submissions/partials/submission-lead.html", {"submission": submission} ) @@ -296,6 +299,9 @@ def partial_reviews_decisions(request: HttpRequest) -> HttpResponse: @login_required def partial_meta_terms_card(request, pk): submission = get_object_or_404(ApplicationSubmission, pk=pk) + has_permission( + "submission_view", request.user, object=submission, raise_exception=True + ) meta_terms = submission.meta_terms.all() ctx = {"meta_terms": meta_terms, "submission": submission} return render(request, "submissions/partials/meta-terms-card.html", ctx) From fa0496087d43344cf603a85a47f60299a39534cd Mon Sep 17 00:00:00 2001 From: Fredrik Jonsson Date: Wed, 13 May 2026 11:50:27 +0200 Subject: [PATCH 2/4] Set secure cookies on production by default. --- hypha/settings/base.py | 4 ---- hypha/settings/production.py | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/hypha/settings/base.py b/hypha/settings/base.py index 161a6dfbaa..181ac8b0ec 100644 --- a/hypha/settings/base.py +++ b/hypha/settings/base.py @@ -617,10 +617,6 @@ "SECURE_REFERRER_POLICY", "strict-origin-when-cross-origin" ) -if env.bool("COOKIE_SECURE", False): - SESSION_COOKIE_SECURE = True - CSRF_COOKIE_SECURE = True - ELEVATE_COOKIE_SECURE = True # Django Elevate settings # https://django-elevate.readthedocs.io/en/latest/config/index.html diff --git a/hypha/settings/production.py b/hypha/settings/production.py index 8721e2568f..b1135f7484 100644 --- a/hypha/settings/production.py +++ b/hypha/settings/production.py @@ -9,6 +9,11 @@ except ImportError: pass +# Security settings +SESSION_COOKIE_SECURE = True +CSRF_COOKIE_SECURE = True +ELEVATE_COOKIE_SECURE = True + # Mailgun configuration. if env.str("MAILGUN_API_KEY", None): EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend" From 266622fd4eef4e8ef099148fff3d835b3ca78ed1 Mon Sep 17 00:00:00 2001 From: Fredrik Jonsson Date: Wed, 13 May 2026 11:51:30 +0200 Subject: [PATCH 3/4] Check next redirect with url_has_allowed_host_and_scheme. --- hypha/apply/determinations/views.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hypha/apply/determinations/views.py b/hypha/apply/determinations/views.py index a2cfb5789d..b1e0a486f4 100644 --- a/hypha/apply/determinations/views.py +++ b/hypha/apply/determinations/views.py @@ -9,6 +9,7 @@ from django.urls import reverse_lazy from django.utils import timezone from django.utils.decorators import method_decorator +from django.utils.http import url_has_allowed_host_and_scheme from django.utils.translation import gettext as _ from django.views.generic import CreateView, DetailView, UpdateView from wagtail.models import Site @@ -261,10 +262,14 @@ def form_valid(self, form): return response def get_success_url(self): - try: - return self.request.GET["next"] - except KeyError: - return reverse_lazy("apply:submissions:list") + next_url = self.request.GET.get("next") + if next_url and url_has_allowed_host_and_scheme( + next_url, + allowed_hosts={self.request.get_host()}, + require_https=self.request.is_secure(), + ): + return next_url + return reverse_lazy("apply:submissions:list") @method_decorator(staff_required, name="dispatch") From 152e4c230f2a0ce90a462e62a7805e5011f36282 Mon Sep 17 00:00:00 2001 From: Fredrik Jonsson Date: Wed, 13 May 2026 14:43:15 +0200 Subject: [PATCH 4/4] Update docs. --- docs/setup/administrators/configuration.md | 8 -------- docs/setup/deployment/production/stand-alone.md | 1 - 2 files changed, 9 deletions(-) diff --git a/docs/setup/administrators/configuration.md b/docs/setup/administrators/configuration.md index f7158a89ad..f71d70f371 100644 --- a/docs/setup/administrators/configuration.md +++ b/docs/setup/administrators/configuration.md @@ -283,14 +283,6 @@ On Heroku, set to true if deploying to Heroku. ---- -Secure cookies - -Set this to enable Djangos settings for secure cookies. - - COOKIE_SECURE = env.bool('COOKIE_SECURE', False) - ----- - Machine translation settings for applications See [here](machine-translations.md) for more information on setting up machine translations diff --git a/docs/setup/deployment/production/stand-alone.md b/docs/setup/deployment/production/stand-alone.md index 93865305a7..b7171c1dff 100644 --- a/docs/setup/deployment/production/stand-alone.md +++ b/docs/setup/deployment/production/stand-alone.md @@ -236,7 +236,6 @@ Here is a list of settings that can be set as environment variables or in a `hyp ```text CACHE_CONTROL_MAX_AGE: 14400 -COOKIE_SECURE: true DJANGO_SETTINGS_MODULE: hypha.settings.production EMAIL_HOST: example.org ORG_EMAIL: hello@example.org