Opened 5 weeks ago
Last modified 12 days ago
#36000 assigned Cleanup/optimization
Update default from http to https in urlize when protocol not provided
Reported by: | Saravana | Owned by: | Saravana |
---|---|---|---|
Component: | Template system | Version: | 5.1 |
Severity: | Normal | Keywords: | |
Cc: | Saravana | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description (last modified by )
In django/utils/html.py
, urlize
there is:
url = smart_urlquote("http://%s" % html.unescape(middle))
When user input does not include a protocol it defaults to http (Insecure Protocol).
Example :
Considered a web app using urlize()
for password reset email template
input = "Password reset link myapp.com/password/reset/{token}"
output:
"Password reset link <a href="http://myapp.com/password/reset/{token}"/>"
so when end user of myapp clicks it the url with token sent in http insecure protocol.
This behavior could potentially lead to man-in-the-middle attacks
Suggested Fix:
Default to HTTPS: If the URL doesn't specify a protocol, Django could default to https://
Change History (4)
comment:1 by , 5 weeks ago
Description: | modified (diff) |
---|---|
Has patch: | unset |
Summary: | Insecure URL Handling (HTTP Protocol Default) in urlize → Update default from http to https in urlize when protocol not provided |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 5 weeks ago
Component: | HTTP handling → Template system |
---|
comment:3 by , 5 weeks ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:4 by , 12 days ago
I think we can use a plan similar to how #34380 shook out, with a plan like:
- Introduce a transitional setting (
URLIZE_ASSUME_HTTPS
) that defaults toFalse
. This goes on the deprecation plan for removal in N+2 versions. - When the responsible code path is hit (which should be fairly rare as it only applies to limited domains), check the setting. If it’s
False
, warn and use 'http', otherwise use 'https'.
Thank you!
Note that the security team discussed this and agreed this can be handled publicly. This is similar to #34380.