views:

139

answers:

3

Is it safe to let users make their own Django templates with a set of pre-defined variables, and then render this template on the server? I would only pass a very limited set of parameters to render, all of which are strings. Templates would be something like:

hey, my name is {{name}}.

So, the question is, are there any django template tags that can be abused to get information that users are not supposed to get? I'm most worried about the {% url %} tag.

P.S.

I noticed this question after filling out the title, however, my question is slightly different. I will probably allow no HTML/javascript at all, use Textile/Markdown, or find a way to restrict HTML to a very basic set of tags.

+1  A: 

Well, from a server-side perspective it's safe (probably, no one has ever audited it), however the users could obviously generate any Javascript they wanted to perform XSS attacks.

Alex Gaynor
+2  A: 

include and ssi looks too dangerous for my taste, especially ssi which uses absolute paths. My opinion is that this is too risky business.

Łukasz
+1  A: 

There're three main risks:

  1. Users modifying the data. For example, rendering {{ request.user.kill }} will trigger kill() call during value lookup. To prevent this, you should set kill.alters_data = True in your model code. All built-in model methods that modify data are already marked, so the risk is only associated with your own methods or ones provided by poorly-written 3rd party apps.

  2. Users directly accessing data they should not see. When RequestContext is used (which is most of the time), there're many variables added to template rendering context. Add user-defined templates and you're getting quite dangerous mix, because user can view anything added by any context processor.

  3. Users accessing data they should not see through relations. When you pass model instance to template, its relations could be travesred futher than you could expect: {{ current_user.corporate_account.owner.ssn }} Oops... A good preventive measure would be carefully reviewing your model relations to make sure you're not exposing something sensitive.

Overall, I'd say it is safe as long as you are aware of risks above and render user-supplied strings separately from regular templates. And make sure you eplicitly forbid {% debug %}, {% include %}. {% ssi %} template tags, as they can give away quite sensitive information. Maybe you can play it safe and only allow variables and filters and forbid control tags altogether.

Alex Lebedev
If I use `Template("My name is {{key}}").render({'key':'value_pairs'})`, that doesn't pass any variables except those in the dictionary, so the user would not have access to `{{ request }}`? And if all the variables are _strings_, I'd only have to worry about `{% ssi %}, {% include %}` etc?
Noio
Yes, that's exactly what I ment as "render separately from regular templates". You need to worry about control tags and model methods only.
Alex Lebedev