Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why and When to use Django mark_safe() function

After reading the document, the function of mark_safe() is still unclear. I guess it is related to CSRF stuff. But why and when shall the mark_safe() be used?

Here is the documentation

mark_safe(s)

Explicitly mark a string as safe for (HTML) output purposes. The returned object can be used everywhere a string or unicode object is appropriate.

Can be called multiple times on a single string.

For building up fragments of HTML, you should normally be using django.utils.html.format_html() instead.

String marked safe will become unsafe again if modified. For example:

like image 639
day Avatar asked Sep 26 '15 16:09

day


People also ask

What is Mark_safe in Django?

mark_safe tells django templates that a string should be used AS IS, from your python code. Normally this is not what you want. Here is an example where python code should output <br /> for the template, which is not escaped.

What is utils PY Django?

Django Utils is a collection of small Django helper functions and classes which make common patterns shorter and easier.


2 Answers

Django is a framework, which tries to do "the right" thing by default. This means when you do the most simple thing, you're propably doing the right thing.

Now let's look at some template in php and python:

PHP:

<? echo $foo ?> 

May give:

<script src="evil"> 

Django:

{{ foo }} 

Gives with the same input:

&gt;script src="evil"&lt; 

Now assume, you want to place a link <a href="link">text</a>. Then django will render it as text using &lt;&gt; again. If you know what you're doing, you can now use mark_safe to indicate that the text is trusted (i.e. not coming from userinput).

Usually you will use {{ foo|safe }} or {% autoescape off %}{{ foo }}{% endautoescape %} in your templates as django programmer, which is more clear when the string is declared as being safe.

So, where is mark_safe used? When you write own templatetags or filters, then you need to mark the string as safe from python, because the developer will assume, that {{ foo|mylinkifyfunction }} does the right thing (i.e. it escapes the url foo, but does not escape the <a href=""></a> around the url).

like image 74
allo Avatar answered Oct 15 '22 14:10

allo


It's also worth noting that when building HTML code fragments it's advised to use format_html(...) function instead of mark_safe and escaping all its arguments.

So, instead of writing:

mark_safe("%s <b>%s</b> %s" % (     some_html,     escape(some_text),     escape(some_other_text), )) 

You should instead use:

format_html("{} <b>{}</b> {}",     mark_safe(some_html),     some_text,     some_other_text, ) 

This has the advantage that you don’t need to apply escape() to each argument and risk a bug and an XSS vulnerability if you forget one.

like image 35
radoh Avatar answered Oct 15 '22 12:10

radoh