diff options
author | Armin Ronacher <armin.ronacher@active-4.com> | 2014-01-10 10:40:51 +0000 |
---|---|---|
committer | Armin Ronacher <armin.ronacher@active-4.com> | 2014-01-10 10:40:51 +0000 |
commit | acb672b6a179567632e032f547582f30fa2f4aa7 (patch) | |
tree | 0d7c3a1e689e52602f03a7b3370af78d0cb7c69f | |
parent | 701e9ada2b6968cf2bc41a3c1d4235922ce164f5 (diff) | |
download | jinja2-acb672b6a179567632e032f547582f30fa2f4aa7.tar.gz |
Fixed a security issue with temporary files on the filesystem cache on UNIX.
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | jinja2/bccache.py | 29 |
2 files changed, 32 insertions, 2 deletions
@@ -7,6 +7,11 @@ Version 2.7.2 - Prefix loader was not forwarding the locals properly to inner loaders. This is now fixed. +- Security issue: Changed the default folder for the filesystem cache to be + user specific and read and write protected on UNIX systems. See `Debian bug + 734747`_ for more information. + +.. _Debian bug 734747: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=734747 Version 2.7.1 ------------- diff --git a/jinja2/bccache.py b/jinja2/bccache.py index f2f9db6..433a480 100644 --- a/jinja2/bccache.py +++ b/jinja2/bccache.py @@ -15,7 +15,9 @@ :license: BSD. """ from os import path, listdir +import os import sys +import errno import marshal import tempfile import fnmatch @@ -189,7 +191,9 @@ class FileSystemBytecodeCache(BytecodeCache): two arguments: The directory where the cache items are stored and a pattern string that is used to build the filename. - If no directory is specified the system temporary items folder is used. + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. The pattern can be used to have multiple separate caches operate on the same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` @@ -202,10 +206,31 @@ class FileSystemBytecodeCache(BytecodeCache): def __init__(self, directory=None, pattern='__jinja2_%s.cache'): if directory is None: - directory = tempfile.gettempdir() + directory = self._get_default_cache_dir() self.directory = directory self.pattern = pattern + def _get_default_cache_dir(self): + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == 'n': + return tmpdir + if not hasattr(os, 'getuid'): + raise RuntimeError('Cannot determine safe temp directory. You ' + 'need to explicitly provide one.') + + dirname = '_jinja2-cache-%d' % os.getuid() + actual_dir = os.path.join(tmpdir, dirname) + try: + os.mkdir(actual_dir, 0700) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + return actual_dir + def _get_cache_filename(self, bucket): return path.join(self.directory, self.pattern % bucket.key) |