Opened 5 years ago
Closed 5 years ago
#31287 closed Cleanup/optimization (wontfix)
Rename mark_safe and "safe" template filters to something less safe sounding
Reported by: | Adam Johnson | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Josh Smeaton | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
As discussed on django-developers in Jan 2018: https://groups.google.com/forum/#!msg/django-developers/AvgxWR-0VrE/b8a3g8q-AwAJ . And occasionally brought up again in other community forums, many developers reporting overuse of mark_safe()
in real world projects.
Copying Stuart Cox's first post from the mailing list thread:
In my experience, misuse of
mark_safe()
— i.e. marking stuff safe which isn’t actually safe (e.g. HTML from a rich text input) — is one of the biggest causes of XSS vulnerabilities in Django projects.
The docs warn to be careful, but unfortunately I think Django devs have just got too used to
mark_safe()
being the way to insert HTML in a template. And it’s easy for something that was safe when it was authored (e.g. calling mark_safe() on a hard-coded string) to be copied / repurposed / adapted into a case which is no longer be safe (e.g. that string replaced with a user-provided value).
Some other frameworks use scary sounding names to help reinforce that there are dangers around similar features, and that this isn’t something you should use in everyday work — e.g. React’s dangerouslySetInnerHTML.
Relatedly, this topic suggested making it more explicit that mark_safe() refers to being safe for use in HTML contexts (rather than JS, CSS, SQL, etc).
Combining the two, it would be great if Django could rename mark_safe() to dangerously_trust_html(), |safe to |dangerously_trust_html, @csrf_exempt to @dangerously_csrf_exempt, etc.
Developers who know what they’re doing with these could then be encouraged to create suitable wrappers which handle their use case safely internally — e.g.:
@register.filter def sanitize_and_trust_html(value): # Safe because we sanitize before trusting return dangerously_trust_html(bleach.clean(value))
Change History (2)
comment:1 by , 5 years ago
comment:2 by , 5 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Yeah, look... I see it... But without a consensus for the change on the mailing list I don't see grounds for a ticket. The case needs to be made there.
Pending something like that, I don't feel we can just bypass the list and Accept a ticket here.
I hope that makes sense.
Meh... You will annoy thousands of devs having to rename multiple occurrences of those names, with IMHO a very small gain. EIther the developer is sensible to security coding and she's probably already careful about those, or the developer doesn't care and just wants to see its string be shown properly, whatever the name of the function is.
TL;DR I'm not convinced.