from django.utils.functional import wraps from django import template # Default tag whitelist whitelist_tags = [ 'comment', 'csrf_token', 'cycle', 'filter', 'firstof', 'for', 'if', 'ifchanged', 'now', 'regroup', 'spaceless', 'templatetag', 'url', 'widthratio', 'with' ] # Default filter whitelist whitelist_filters = [ 'add', 'addslashes', 'capfirst', 'center', 'cut', 'date', 'default', 'default_if_none', 'dictsort', 'dictsortreversed', 'divisibleby', 'escape', 'escapejs', 'filesizeformat', 'first', 'fix_ampersands', 'floatformat', 'force_escape', 'get_digit', 'iriencode', 'join', 'last', 'length', 'length_is', 'linebreaks', 'linebreaksbr', 'linenumbers', 'ljust', 'lower', 'make_list', 'phone2numeric', 'pluralize', 'pprint', 'random', 'removetags', 'rjust', 'safe', 'safeseq', 'slice', 'slugify', 'stringformat', 'striptags', 'time', 'timesince', 'timeuntil', 'title', 'truncatewords', 'truncatewords_html', 'unordered_list', 'upper', 'urlencode', 'urlize', 'urlizetrunc', 'wordcount', 'wordwrap', 'yesno' ] # Custom libraries to add to builtins extra_libraries = [ 'myproject.myapp.templatetags.extra_tags', 'myproject.myapp.templatetags.extra_filters', ] def use_safe_templates(tags=None, filters=None, extra=None): """ Cleans the builtin template libraries before running the function (restoring the builtins afterwards). Removes any builtin tags and filters that are not enumerated in `tags` and `filters`, and adds the extra library modules in `extra` to the builtins. Does not catch any template exceptions (notably, TemplateSyntaxError and TemplateDoesNotExist may be raised). """ def decorate(func): @wraps(func) def wrapped(*args, **kwargs): # Clean out default libraries # Note: template.builtins is merely a convenience import, we have to work # with template.base.builtins for this to work right. template.base.builtins, default_libs = [], template.base.builtins try: # Construct new builtin with only whitelisted tags/filters whitelist = template.Library() for lib in default_libs: for tag in lib.tags: if tag in tags: whitelist.tags[tag] = lib.tags[tag] for filter in lib.filters: if filter in filters: whitelist.filters[filter] = lib.filters[filter] # Install whitelist library and extras as builtins template.base.builtins.append(whitelist) [template.add_to_builtins(e) for e in extra] return func(*args, **kwargs) finally: # Restore the builtins to their former defaults template.base.builtins = default_libs return wrapped if callable(tags): # @use_safe_templates func = tags tags = whitelist_tags filters = whitelist_filters extra = extra_libraries return decorate(func) else: # @use_safe_templates(...) tags = tags or whitelist_tags filters = filters or whitelist_filters extra = extra or extra_libraries return decorate