Skip to content

Commit acb672b

Browse files
committed
Fixed a security issue with temporary files on the filesystem cache on UNIX.
1 parent 701e9ad commit acb672b

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

CHANGES

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ Version 2.7.2
77

88
- Prefix loader was not forwarding the locals properly to
99
inner loaders. This is now fixed.
10+
- Security issue: Changed the default folder for the filesystem cache to be
11+
user specific and read and write protected on UNIX systems. See `Debian bug
12+
734747`_ for more information.
13+
14+
.. _Debian bug 734747: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=734747
1015

1116
Version 2.7.1
1217
-------------

jinja2/bccache.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
:license: BSD.
1616
"""
1717
from os import path, listdir
18+
import os
1819
import sys
20+
import errno
1921
import marshal
2022
import tempfile
2123
import fnmatch
@@ -189,7 +191,9 @@ class FileSystemBytecodeCache(BytecodeCache):
189191
two arguments: The directory where the cache items are stored and a
190192
pattern string that is used to build the filename.
191193
192-
If no directory is specified the system temporary items folder is used.
194+
If no directory is specified a default cache directory is selected. On
195+
Windows the user's temp directory is used, on UNIX systems a directory
196+
is created for the user in the system temp directory.
193197
194198
The pattern can be used to have multiple separate caches operate on the
195199
same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s``
@@ -202,10 +206,31 @@ class FileSystemBytecodeCache(BytecodeCache):
202206

203207
def __init__(self, directory=None, pattern='__jinja2_%s.cache'):
204208
if directory is None:
205-
directory = tempfile.gettempdir()
209+
directory = self._get_default_cache_dir()
206210
self.directory = directory
207211
self.pattern = pattern
208212

213+
def _get_default_cache_dir(self):
214+
tmpdir = tempfile.gettempdir()
215+
216+
# On windows the temporary directory is used specific unless
217+
# explicitly forced otherwise. We can just use that.
218+
if os.name == 'n':
219+
return tmpdir
220+
if not hasattr(os, 'getuid'):
221+
raise RuntimeError('Cannot determine safe temp directory. You '
222+
'need to explicitly provide one.')
223+
224+
dirname = '_jinja2-cache-%d' % os.getuid()
225+
actual_dir = os.path.join(tmpdir, dirname)
226+
try:
227+
os.mkdir(actual_dir, 0700)
228+
except OSError as e:
229+
if e.errno != errno.EEXIST:
230+
raise
231+
232+
return actual_dir
233+
209234
def _get_cache_filename(self, bucket):
210235
return path.join(self.directory, self.pattern % bucket.key)
211236

0 commit comments

Comments
 (0)