Skip to content

Update to Django 6 + patch of 2 important vuln#566

Merged
altf4arnold merged 2 commits intomainfrom
upd_vuln
Mar 6, 2026
Merged

Update to Django 6 + patch of 2 important vuln#566
altf4arnold merged 2 commits intomainfrom
upd_vuln

Conversation

@Mortinat
Copy link
Contributor

@Mortinat Mortinat commented Mar 6, 2026

@altf4arnold altf4arnold merged commit 523207b into main Mar 6, 2026
3 checks passed
@altf4arnold altf4arnold deleted the upd_vuln branch March 6, 2026 23:13
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the project’s runtime stack (Python/Django + Docker images) while also addressing web security issues (XSS sanitization for rendered Markdown and an open-redirect fix on login).

Changes:

  • Upgrade to Django 6.x, Python 3.14, and bump multiple dependencies/images (uv lockfile, Docker, CI workflows).
  • Replace prior Markdown “safe_mode” usage with nh3-based HTML sanitization for wiki/flatpages/email content.
  • Harden authentication/UX flows by validating next URLs on login and enforcing POST-only for certain profile actions.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
pyproject.toml Updates Python/Django requirements and adds nh3.
uv.lock Refreshes the full dependency lock to match new runtime/deps.
Dockerfile Moves base image to Python 3.14.
.github/workflows/push.yml Updates CI to run on Python 3.14.
.github/workflows/pull_request.yml Updates PR checks to run on Python 3.14.
docker-compose.yml Bumps Redis/Postgres images (notably Postgres 12 → 17).
upgrade_postgres.sh Adds a scripted Postgres 12 → 17 migration workflow.
backup_db.sh Updates DB backup to use docker compose and new dump method.
users/views.py Fixes open redirect on login; requires POST for pamela show/hide actions.
incubator/templatetags/formatting.py Centralizes Markdown rendering + sanitization via nh3.
manmail/models.py Sanitizes newsletter HTML output via nh3.
incubator/settings.py Adds SecurityMiddleware + production security settings; updates/cleans config.
incubator/urls.py Removes django_nyt notifications route and reformats URL patterns.
incubator/apiurls.py Replaces deprecated url() usage with re_path().
projects/migrations/0008_alter_project_dependencies.py Adds a migration to align the dependencies field definition.
nginx/Dockerfile Bumps nginx base image version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +325 to +333
# Security settings (applied in production when DEBUG=False)
if not DEBUG:
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_CONTENT_TYPE_NOSNIFF = True
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enabling SECURE_SSL_REDIRECT = True in production can cause redirect loops when the app is behind a reverse proxy (e.g. Traefik/nginx) unless Django is configured to trust the forwarded proto. Consider adding SECURE_PROXY_SSL_HEADER (and ensuring X-Forwarded-Proto is forwarded to Django) so request.is_secure() is correct in production.

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +38
# echo "[1/6] Dumping database from PostgreSQL 12..."
# docker compose exec -T db pg_dumpall -U "$DB_USER" > "$DUMP_FILE"
# DUMP_SIZE=$(du -h "$DUMP_FILE" | cut -f1)
# echo " Dump complete: $DUMP_FILE ($DUMP_SIZE)"
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dump step is commented out, but the script later restores from $DUMP_FILE. With set -euo pipefail, this will fail because the dump file is never created. Either re-enable the dump step or change the script so restore only runs after a successful dump (and consider failing fast if the dump file is missing).

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +68
echo "[6/6] Restoring dump into PostgreSQL 17..."
docker compose exec -T db psql -U "$DB_USER" -d "$DB_NAME" < "$DUMP_FILE"
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pg_dumpall output typically contains cluster-level statements (roles, CREATE DATABASE, \connect, etc.). Restoring it by piping into psql -d "$DB_NAME" can lead to errors (e.g. database already exists) and may partially restore without failing the script. Consider using pg_dump/pg_restore for the single DB, or ensure restore runs with ON_ERROR_STOP and targets the right scope (globals vs db dump).

Copilot uses AI. Check for mistakes.
mkdir -p /home/incubator/dumps/$(date +"%y-%m")
docker-compose -f /home/incubator/docker/apps/incubator/docker-compose.yml exec db /usr/local/bin/pg_dump --dbname="incubator_db" --username="incubator" -f /backup.dump
docker cp incubator_db_1:/backup.dump /home/incubator/dumps/$(date +"%y-%m")/$(date +"%y-%m-%d").dump
docker compose -f /home/incubator/docker/apps/incubator/docker-compose.yml exec -T db pg_dumpall --username="incubator" > /home/incubator/dumps/$(date +"%y-%m")/$(date +"%y-%m-%d").sql
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This switches backups from pg_dump (single DB) to pg_dumpall (entire cluster). pg_dumpall often requires superuser permissions and produces a plain SQL script that may be harder to restore selectively. If the intent is to back up only incubator_db, consider using pg_dump (optionally in custom format) instead of pg_dumpall.

Suggested change
docker compose -f /home/incubator/docker/apps/incubator/docker-compose.yml exec -T db pg_dumpall --username="incubator" > /home/incubator/dumps/$(date +"%y-%m")/$(date +"%y-%m-%d").sql
docker compose -f /home/incubator/docker/apps/incubator/docker-compose.yml exec -T db pg_dump --username="incubator" --dbname="incubator_db" > /home/incubator/dumps/$(date +"%y-%m")/$(date +"%y-%m-%d").sql

Copilot uses AI. Check for mistakes.
return SafeText(html)
@register.filter(is_safe=False, name="unsafeMarkdown")
@stringfilter
def unsafe_markdown(value):
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unsafeMarkdown filter now uses the same sanitized rendering path as the markdown filter. This makes the name misleading (templates like flatpages/default.html still use unsafeMarkdown expecting less-restricted output). Consider renaming the filter (and updating templates) or adding an explicit comment/docstring explaining that unsafeMarkdown is intentionally sanitized now.

Suggested change
def unsafe_markdown(value):
def unsafe_markdown(value):
"""
Render markdown to sanitized HTML.
Despite the name, this filter uses the same sanitized rendering path as the
``markdown`` filter via ``_render_markdown``. It is retained for backwards
compatibility with existing templates that refer to ``unsafeMarkdown``, and
does not intentionally bypass HTML sanitization.
"""

Copilot uses AI. Check for mistakes.
Comment on lines +319 to +323
DEFAULT_FILE_STORAGE = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEFAULT_FILE_STORAGE is being set to a dict, but Django expects DEFAULT_FILE_STORAGE to be a string setting (and on newer Django versions, storage backends are configured via STORAGES). As-is, this will likely break file storage initialization. Consider replacing this with STORAGES = {"default": {"BACKEND": ...}} (or set DEFAULT_FILE_STORAGE to the backend path string if targeting older Django).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants