Is there a safe alternative to striptags in Jinja?

Viewed 2676

I noticed this behaviour while using pelican:

Template('<p>{{text|striptags|striptags}}</p>').render(text='&lt;script src="http://chezsoi.org"/&gt;')

is getting rendered as:

<script src="http://chezsoi.org"/>

I was counting on striptags output to be free of any HTML tag, which is false. Hence my question: is there a "safer" alternative to the builtin striptags filter ?

I know that a quick solution is to chain calls to striptags:

'{{ <p>text|striptags|striptags|striptags }}</p>'

But in case an attacker has control over text content, they can double-HTML-escape the string, and so on and so on.

2 Answers

Pelican does not enable Jinja's autoescape by default (as for now, version 4.5.1), which in my opinion is not a good idea. Article's title and summary should not contain chars like < >, or you won't get a correct output result. For theme coders, it is not convenient, and prone to bugs. In fact, only few variables should be output as what it is, most variables should be encoded when output.

You can enable it in your config file:

JINJA_ENVIRONMENT = {
    'autoescape': True,
}

And don't forget to modify your template accordingly. Remove filters like striptags and escape to avoid double-escaping, and add safe filter to some output point where should not do escaping:

{{ article.content | safe }}

If you are not sure, keep an original vesion of generated static files, and compare with it later to see what is changed.

Related