Untrusted templates in Python - what is a safe library to use? - python

I am building a library that will be used in several Python applications. It get multilingual e-mail templates from an RMDBS, and then variable replacement will be performed on the template in Python before the e-mail is sent.
In addition to variable replacement, I need the template library to support if, elif, and for statements in the templates.
I use Mako for most my projects, and also looked at Tempita as it doesn't provide a lot of features I don't need.
The concern I have is untrusted code execution - can someone point me at a template solution for Python that either does not support code execution, or will allow me to disable it?

From the Django book:
For that reason, it’s impossible to call Python code directly within Django templates. All “programming” is fundamentally limited to the scope of what template tags can do. It is possible to write custom template tags that do arbitrary things, but the out-of-the-box Django template tags intentionally do not allow for arbitrary Python code execution.
Give Django templates a try. It's a little tricky to set up outside of a Django app -- something to do with DJANGO_SETTINGS_MODULE, search around -- but may be trusted.

Have you checked out Jinja2? It's pretty much what you're talking about, and it's a great mix of powerful while keeping things simple and not giving the designer too much power. :)
If you've used Django's template system, it's very similar (if not based off of?) Jinja.

Related

Django - How to port scripts to django

Before I ask my question I need to give some context:
I wrote a simple python script that read linux's syslog file and search for certain strings. I have other similar scripts like these (scripts that do file system stuff, scripts that interact with other servers and so on). Most of these scripts write simple write stuff to stdout.
I would like to port these scripts to a web-server so I could simple browser to https://server/syslog and get the same output that I would get by running the script on the command line interface.
According with my research Django seems to be a great choice. I followed some Django tutorials and I was capable of developing some basic django web apps.
My question is: Since django does not have a "controller" where should I place the scripts code? My best bet in the view, but according with djangos documentation it does not make sence.
Extracted from django doc: In our interpretation of MVC, the “view” describes the data that gets presented to the user. It’s not necessarily how the data looks, but which data is presented. The view describes which data you see, not how you see it. It’s a subtle distinction.
The description of MVC is not so important. The typical use of django is for database backed web applications. And this describes a design pattern or paradigm for that. It's completely possible to use django in other ways as well.
If you want to build a django app that is a web interface for your existing scripts, you might not even need the django ORM at all. In any case, you can put as much or as little logic in your view as you want. Your use case might just not fit neatly into the MVC or MVT paradigm. Django views are just python functions (or classes, but Django class based views are more tightly coupled with the ORM).
I would recommend:
leaving your scripts largely as they are, but wrap the parts you want to reuse as
functions. You can keep them functional as standalone scripts with an
if __name__=='__main__':
block to call the functions.
Import the functions to views.py - it doesn't matter where they are as long as your server will always be able to find them. I put mine right in the app directory.
Call the function(s) in your view(s), and return the text to a HttpResponse object which you return from the view. (I think this is more direct than creating a template and a context and calling render, but its not what I usually do so there may be some issues?)
Thats bit old code - but you will get enough idea to start - check https://github.com/alex2/django_logtail (Django_LogTail)

Python template system like Smarty or Radius

Is there a Python template library similar to Smarty or Radius (Ruby's Movable Type-like template library) out there?
The python wiki entry on this topic is here: http://wiki.python.org/moin/Templating
The two well-known template systems other than Django are cheetah and jinja.
Django's templating system is not especially powerful, by design, because that discourages any logic other than pure presentation logic in the templates. This is something that I value, having used JSP and ASP.
Jinja is pretty much a superset of Django's templates, except that if you wanted you could embed all of your view code in it ( I wouldn't ).
Cheetah looks rather more like JSP.
Any of these can be used with Django (the full stack framework), or you could use one of the microframeworks or "bundled" frameworks. See this wiki page: http://wiki.python.org/moin/WebFrameworks
AFAIK, Django. It has an excellent templating system.
It's slightly different from PHP, because of the following:
Variables and methods must be passed in to the template renderer.
Variables and methods are noted by {{ braces }}.
Tags (Django's version of PHP flow control statements), are denoted like {% if x %}, followed by a loop termination (like {% endif %}.
You can call functions directly from the template, but they will not accept any arguments.
There's a lot more, but I would highly recommend that you read the Django book.
Just one note: from personal experience, Django's ORM isn't very good for legacy database integration, so if you're looking for that, you might want to try SQLalchemy.
EDIT: Marcin had a good summary - Django's templating system, by design, encourages the separation of presentation and processing logic (i.e., loose coupling).
EDIT 2: There's also mako, which has a more PHP-like syntax.

Is there a good way to apply pychecker/pylint to the python code in Tornado templates?

I am using Tornado 2.0 (Python 2.6.5) to build a simple web app.
Naturally, my Tornado templates contain snippets of Python code. For my non-template code, I am using pychecker and pylint to check for errors, etc.
However, obviously pychecker and pylint can't be run over the templates directly, b/c the templates are not python files proper (for non-Tornado users: they are html-like snippets w/ some control sequences and embedded python code).
So, my question is: can anyone suggest a good way to apply pychecker/pylint to the python code in these template files? Presumably this would involve extracting the code from the files.
I can hazard a few guesses as to how to do this, but I am curious if other people perceive this as a problem and what solutions they have pursued. I am still fairly new to web app design/construction so I am interested in answers guided by practical experience.
You need to use view class pattern to avoid cluttering your template with Python code which cannot be analyzed.
Create a Python class to process your view, instead of function
Have all "template logic" code as class methods. Your template calls them like {{ view.get_full_name }} and def get_full_name(self): return self.item.first_name + " " + self.item.last_name
Make instance out of your class
make call() as starting point for your processing
Pass "self" to your template as a context var
Some instructions for Django, but generally all Python frameworks (Pyramid, Zope) follow the same pattern:
Class views in Django
"$yourframeworkname view class" should yield more tutorials in Google.

Django: allow safe html tags

Im looking into XSS with various frameworks and CMS and whether they provide methods in protecting against it (not just programmaticly avoiding the situation).
I know that in Djangos templating language you can specify a variable as |safe I want to be able to allow actually safe html tags so the user can format text (simple things like etc), but strip such things as , onload attributes etc.
I would like to know whether Django recommends a method in doing this, not just using Python. I hope this makes sense
Jason
One of the core concepts of Django is that it's Python, and any Python lib should be usable with Django. They won't recreate the wheel unless there is good reason to. I believe HTML scrubbing/sanitizing is one of the things they've decided not to recreate.
BeautifulSoup is the python library you want to look into for any scrubbing/sanitizing though.

How can I provide safety template for user to modify with python?

I am building a multi-user web application. Each user can have their own site under my application. I am considering how to allow user to modify template without security problem? I have evaluated some python template engine. For example, genshi, it is a pretty wonderful template engine, but however it might be dangerous to allow user to modify genshi template. It have a syntax like this:
<?python
?>
This syntax allow you run whatever you want python can do. I notice that it seems can be shutdown by passing some parameter. But there are still a lots of potential problems. For example, user can access build-in functions, and methods of passed variables. For example, if I pass a ORM object to template. It might contain some method and variable that I don't want to allow user touch it. May like this:
site.metadata.connection.execute("drop table xxx")
So my question is how can I allow user to modify template of their site without security problems? Any python template engine can be used.
Thanks.
Jinja2 is a Django-ish templating system that has a sandboxing feature. I've never attempted to use the sandboxing, but I quite like Jinja2 as an alternative to Django's templates. It still promotes separation of template from business logic, but has more Pythonic calling conventions, namespacing, etc.
Jinja2 Sandbox
Look at Django templte engine. It does not support execution of arbitrary python code and all accessible variables must be passed into template explicity. This should be pretty good foundation for building user-customizable pages. Beware that you'll still need to handle occasional syntax errors from your users.
In rails there's something called liquid. You might take a look at that to get some ideas. Another idea: at the very least, one thing you could do is to convert your objects into simple dictionary - something like a json representation, and then pass to your template.
The short answer is probably "you can't".
The best you can probably do is to trap the individual users in virtual machines or sandboxes.

Categories

Resources