diff --git a/dev/build/Dockerfile b/dev/build/Dockerfile index e57fecd5f22..55a308d7ce7 100644 --- a/dev/build/Dockerfile +++ b/dev/build/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/ietf-tools/datatracker-app-base:20260410T1557 +FROM ghcr.io/ietf-tools/datatracker-app-base:20260512T1629 LABEL maintainer="IETF Tools Team " ENV DEBIAN_FRONTEND=noninteractive diff --git a/dev/build/TARGET_BASE b/dev/build/TARGET_BASE index f430037c094..71a59ed2661 100644 --- a/dev/build/TARGET_BASE +++ b/dev/build/TARGET_BASE @@ -1 +1 @@ -20260410T1557 +20260512T1629 diff --git a/ietf/doc/migrations/0034_alter_dochistory_keywords_alter_document_keywords.py b/ietf/doc/migrations/0034_alter_dochistory_keywords_alter_document_keywords.py new file mode 100644 index 00000000000..2b89b67e88c --- /dev/null +++ b/ietf/doc/migrations/0034_alter_dochistory_keywords_alter_document_keywords.py @@ -0,0 +1,33 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations, models +import ietf.doc.models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0033_dochistory_keywords_document_keywords"), + ] + + operations = [ + migrations.AlterField( + model_name="dochistory", + name="keywords", + field=models.JSONField( + blank=True, + default=list, + max_length=1000, + validators=[ietf.doc.models.validate_doc_keywords], + ), + ), + migrations.AlterField( + model_name="document", + name="keywords", + field=models.JSONField( + blank=True, + default=list, + max_length=1000, + validators=[ietf.doc.models.validate_doc_keywords], + ), + ), + ] diff --git a/ietf/doc/models.py b/ietf/doc/models.py index cc79b73831e..0af8507f858 100644 --- a/ietf/doc/models.py +++ b/ietf/doc/models.py @@ -157,6 +157,7 @@ class DocumentInfo(models.Model): default=list, max_length=1000, validators=[validate_doc_keywords], + blank=True, ) @property diff --git a/ietf/settings.py b/ietf/settings.py index 50e069ff1a5..8a4587e50a8 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -1261,7 +1261,10 @@ def skip_unreadable_post(record): 'patch/change-oidc-provider-field-sizes-228.patch', 'patch/fix-oidc-access-token-post.patch', 'patch/fix-jwkest-jwt-logging.patch', - 'patch/django-cookie-delete-with-all-settings.patch', + # Patch includes old cookie-delete-with-all-settings and a backport of the fix + # to CVE-2026-35192 from Django 5.2. The patches conflict, so cannot be applied + # separately. + 'patch/django-cookie-delete-settings-and-CVE-2026-35192.patch', 'patch/tastypie-django22-fielderror-response.patch', ] if DEBUG: diff --git a/patch/django-cookie-delete-with-all-settings.patch b/patch/django-cookie-delete-settings-and-CVE-2026-35192.patch similarity index 68% rename from patch/django-cookie-delete-with-all-settings.patch rename to patch/django-cookie-delete-settings-and-CVE-2026-35192.patch index 4ceaf8fceb4..3f625c33bb9 100644 --- a/patch/django-cookie-delete-with-all-settings.patch +++ b/patch/django-cookie-delete-settings-and-CVE-2026-35192.patch @@ -44,9 +44,9 @@ expires="Thu, 01 Jan 1970 00:00:00 GMT", samesite=samesite, ) ---- django/contrib/sessions/middleware.py.orig 2020-08-13 12:12:12.401898114 +0200 -+++ django/contrib/sessions/middleware.py 2020-08-13 12:14:52.690520659 +0200 -@@ -38,6 +38,8 @@ +--- django/contrib/sessions/middleware.py.old 2026-05-12 15:18:07.673997003 +0000 ++++ django/contrib/sessions/middleware.py 2026-05-12 15:18:15.770997007 +0000 +@@ -38,12 +38,15 @@ settings.SESSION_COOKIE_NAME, path=settings.SESSION_COOKIE_PATH, domain=settings.SESSION_COOKIE_DOMAIN, @@ -54,4 +54,23 @@ + httponly=settings.SESSION_COOKIE_HTTPONLY or None, samesite=settings.SESSION_COOKIE_SAMESITE, ) - patch_vary_headers(response, ("Cookie",)) +- patch_vary_headers(response, ("Cookie",)) ++ need_vary_cookie = True + else: +- if accessed: +- patch_vary_headers(response, ("Cookie",)) ++ # If the session was accessed, it must be varied on, regardless of ++ # whether it was modified or will be saved. ++ need_vary_cookie = accessed + if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty: + if request.session.get_expire_at_browser_close(): + max_age = None +@@ -74,4 +77,8 @@ + httponly=settings.SESSION_COOKIE_HTTPONLY or None, + samesite=settings.SESSION_COOKIE_SAMESITE, + ) ++ # With a session cookie set, it must be varied on. ++ need_vary_cookie = True ++ if need_vary_cookie: ++ patch_vary_headers(response, ("Cookie",)) + return response diff --git a/requirements.txt b/requirements.txt index ca9a6740e16..214dfe296f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ botocore>=1.39.15 celery>=5.5.3 coverage>=7.9.2 defusedxml>=0.7.1 # for TastyPie when using xml; not a declared dependency -Django>4.2,<5 +Django>=4.2.30,<5 django-admin-rangefilter>=0.13.3 django-analytical>=3.2.0 django-bootstrap5>=25.1