Skip to content

Replace django-ckeditor (CKEditor 4 is EOL with known XSS issues) #1269

@jonfroehlich

Description

@jonfroehlich

Background

We're currently on django-ckeditor==6.7.3, which bundles CKEditor 4 — end-of-life since June 2023 with known unpatched XSS issues. The package maintainers themselves flag this in the README. It surfaced in the 2026-06-12 audit (codebase-analysis.md, Security/Medium):

requirements.txt (line ~109) — django-ckeditor==6.7.3 bundles end-of-life CKEditor 4 with known unpatched XSS issues. The maintainers themselves flag this.

It's also the single most fragile dependency in our stack — every Django minor-version bump risks new breakage. Replacing it unblocks the planned Django 6.1 LTS upgrade (separate issue, linked).

Where it's used

django-ckeditor powers the rich-text editor in the News admin (and any other RichTextField / RichTextUploadingField we've added). Uploads land in media/uploads/ with filenames generated by website.utils.fileutils.get_ckeditor_image_filename.

$ grep -rn "RichText\|ckeditor" website/ makeabilitylab/

…will show the touch points.

Replacement options

Package Editor Notes
django-ckeditor-5 CKEditor 5 Newer, maintained; separate package, not a drop-in.
django-prose-editor ProseMirror-based Lightweight, modern, active maintenance.
django-tinymce TinyMCE 6+ Well-known, robust, plugin ecosystem.

My current lean: django-prose-editor for simplicity and minimal JS footprint, but worth a 30-min eval of all three before committing.

Scope of work

  • Pick replacement (eval 2-3 candidates)
  • Swap RichTextField → new field type on News (any other models?)
  • Migrate existing News.content HTML — should mostly be portable since we store raw HTML, but verify with a few content-heavy items (e.g. /news/158/)
  • Replace the CKEditor upload endpoint + filename hook (website.utils.fileutils.get_ckeditor_image_filename)
  • Update makeabilitylab/urls.py (currently includes ckeditor/ URLs)
  • Audit existing news items for visual regressions on test before tagging prod
  • Add a regression test that creates a News item with HTML content and asserts it renders escaped/unescaped as expected

Why this is the right next step before Django 6.1 LTS

Both Django and our other fragile packages (sortedm2m_filter_horizontal_widget fork, django-image-cropping) move slowly. CKEditor 4 has the worst combination of (a) actively-known security holes and (b) blocking the next Django LTS upgrade. Doing this in 2026 summer means we're in good shape when 6.1 LTS ships (~Aug 2026).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions