Opened 4 months ago

Closed 5 days ago

Last modified 5 days ago

#36900 closed Bug (fixed)

startproject and startapp do not sanitize filename from Content-Disposition header

Reported by: Natalia Bidart Owned by: Jacob Walls
Component: Core (Management commands) Version: 6.0
Severity: Normal Keywords: startapp startproject
Cc: ar3ph Triage Stage: Ready for checkin
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using django-admin startproject or startapp with a remote --template URL, the download logic trusts the filename value from the HTTP Content-Disposition header and uses it directly to construct a filesystem path.

In TemplateCommand.download(), the header-provided filename is joined with the temporary download directory and passed to shutil.move() without normalization. The filename is not sanitized, allowing the downloaded file to be written outside the command’s designated temporary download directory.

This occurs before archive validation or extraction and affects only local development workflows using remote templates, which are documented to require full audit before use (https://docs.djangoproject.com/en/6.0/ref/django-admin/#cmdoption-startapp-template).

Still, the expected behavior is that downloaded template archives should always remain confined to the temporary download directory, regardless of header-provided filenames.

Change History (13)

comment:1 by jaffar Khan, 4 months ago

Cc: jaffar Khan added

comment:2 by Jacob Walls, 4 months ago

Triage Stage: UnreviewedAccepted

comment:3 by ar3ph, 4 months ago

I can take a look at this.

comment:4 by ar3ph, 4 months ago

Cc: ar3ph added
Owner: set to ar3ph
Status: newassigned

comment:5 by ar3ph, 4 months ago

Has patch: set

Here is a patch for the filename from Content-Disposition header: https://github.com/django/django/pull/20639

Do I need to update/add a test though? I can't find any existing tests for the template command.

in reply to:  5 comment:6 by Natalia Bidart, 4 months ago

Needs documentation: set
Needs tests: set
Patch needs improvement: set

Replying to ar3ph:

Do I need to update/add a test though? I can't find any existing tests for the template command.

Yes, most definitely. Existing tests are located in https://github.com/django/django/blob/main/tests/admin_scripts/tests.py

Setting the flags per PR comments.

comment:7 by ar3ph, 4 months ago

I have updated the code, added a test and updated the release doc: https://github.com/django/django/pull/20639

comment:8 by jaffar Khan, 4 months ago

Cc: jaffar Khan removed

comment:9 by ar3ph, 4 months ago

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

comment:10 by Jacob Walls, 6 days ago

Has patch: unset
Owner: changed from ar3ph to Jacob Walls

comment:11 by Jacob Walls, 6 days ago

Triage Stage: AcceptedReady for checkin

Submitted patch looks in good shape, I added small cosmetic edits in a new PR to prepare to land.

comment:12 by Jacob Walls <jacobtylerwalls@…>, 5 days ago

Resolution: fixed
Status: assignedclosed

In 46c5e76:

Fixed #36900 -- Used safe_join() on downloaded template archive.

comment:13 by Jacob Walls <jacobtylerwalls@…>, 5 days ago

In 74ce178:

[6.1.x] Fixed #36900 -- Used safe_join() on downloaded template archive.

Backport of 46c5e76f0bcc76bfce19ad7ba07f716fc653a822 from main.

Note: See TracTickets for help on using tickets.
Back to Top