summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Ronacher <armin.ronacher@active-4.com>2014-01-10 10:40:51 +0000
committerArmin Ronacher <armin.ronacher@active-4.com>2014-01-10 10:40:51 +0000
commitacb672b6a179567632e032f547582f30fa2f4aa7 (patch)
tree0d7c3a1e689e52602f03a7b3370af78d0cb7c69f
parent701e9ada2b6968cf2bc41a3c1d4235922ce164f5 (diff)
downloadjinja2-acb672b6a179567632e032f547582f30fa2f4aa7.tar.gz
Fixed a security issue with temporary files on the filesystem cache on UNIX.
-rw-r--r--CHANGES5
-rw-r--r--jinja2/bccache.py29
2 files changed, 32 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index 6425de5..17e44ef 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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)