You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-commits@quetz.apache.org by jg...@apache.org on 2006/02/19 20:51:17 UTC
svn commit: r378945 - in /httpd/mod_python/branches/3.2.x: Doc/appendixc.tex
NEWS lib/python/mod_python/Session.py lib/python/mod_python/__init__.py
src/include/mpversion.h test/test.py
Author: jgallacher
Date: Sun Feb 19 11:51:17 2006
New Revision: 378945
URL: http://svn.apache.org/viewcvs?rev=378945&view=rev
Log:
Added check for the validity of the session id. This will fix a potential
directory traversal attack in FileSession.
Ref MODPYTHON-135
Modified:
httpd/mod_python/branches/3.2.x/Doc/appendixc.tex
httpd/mod_python/branches/3.2.x/NEWS
httpd/mod_python/branches/3.2.x/lib/python/mod_python/Session.py
httpd/mod_python/branches/3.2.x/lib/python/mod_python/__init__.py
httpd/mod_python/branches/3.2.x/src/include/mpversion.h
httpd/mod_python/branches/3.2.x/test/test.py
Modified: httpd/mod_python/branches/3.2.x/Doc/appendixc.tex
URL: http://svn.apache.org/viewcvs/httpd/mod_python/branches/3.2.x/Doc/appendixc.tex?rev=378945&r1=378944&r2=378945&view=diff
==============================================================================
--- httpd/mod_python/branches/3.2.x/Doc/appendixc.tex (original)
+++ httpd/mod_python/branches/3.2.x/Doc/appendixc.tex Sun Feb 19 11:51:17 2006
@@ -1,3 +1,17 @@
+\chapter{Changes from Version (3.2.7)\label{app-changes}}
+
+\indexii{Changes from}{version 3.2.7}
+
+ Security Fix
+
+ \begin{itemize}
+ \item
+ Fixed possible directory traversal attack in FileSession. The session
+ id is now checked to ensure it only contains valid characters. This
+ check is performed for all sessions derived from the BaseSession
+ class.
+ \end{itemize}
+
\chapter{Changes from Version (3.1.4)\label{app-changes}}
\indexii{Changes from}{version 3.1.4}
Modified: httpd/mod_python/branches/3.2.x/NEWS
URL: http://svn.apache.org/viewcvs/httpd/mod_python/branches/3.2.x/NEWS?rev=378945&r1=378944&r2=378945&view=diff
==============================================================================
--- httpd/mod_python/branches/3.2.x/NEWS (original)
+++ httpd/mod_python/branches/3.2.x/NEWS Sun Feb 19 11:51:17 2006
@@ -1,3 +1,7 @@
+Feb 19 2006 - 3.2.8 is being tagged
+ 3.2.8 is a security release to fix the possible
+ directory traversal attack in FileSession.
+
Feb 3 2006 - 3.2.7 is being tagged
Jan 16 2006 - 3.2.6 final is being tagged (no changes from 3.2.6b)
Modified: httpd/mod_python/branches/3.2.x/lib/python/mod_python/Session.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/branches/3.2.x/lib/python/mod_python/Session.py?rev=378945&r1=378944&r2=378945&view=diff
==============================================================================
--- httpd/mod_python/branches/3.2.x/lib/python/mod_python/Session.py (original)
+++ httpd/mod_python/branches/3.2.x/lib/python/mod_python/Session.py Sun Feb 19 11:51:17 2006
@@ -29,6 +29,7 @@
import cPickle, cStringIO
import tempfile
import traceback
+import re
COOKIE_NAME="pysid"
DFT_TIMEOUT=30*60 # 30 min
@@ -82,6 +83,19 @@
# Make a number based on current time, pid, remote ip
# and two random ints, then hash with md5. This should
# be fairly unique and very difficult to guess.
+ #
+ # WARNING
+ # The current implementation of _new_sid returns an
+ # md5 hexdigest string. To avoid a possible directory traversal
+ # attack in FileSession the sid is validated using
+ # the _check_sid() method and the compiled regex
+ # validate_sid_re. The sid will be accepted only if len(sid) == 32
+ # and it only contains the characters 0-9 and a-f.
+ #
+ # If you change this implementation of _new_sid, make sure to also
+ # change the validation scheme, as well as the test_Session_illegal_sid()
+ # unit test in test/test.py.
+ # /WARNING
t = long(time.time()*10000)
pid = os.getpid()
@@ -92,6 +106,21 @@
return md5.new("%d%d%d%d%s" % (t, pid, rnd1, rnd2, ip)).hexdigest()
+validate_sid_re = re.compile('[0-9a-f]{32}$')
+
+def _check_sid(sid):
+ ## Check the validity of the session id
+ # # The sid must be 32 characters long, and consisting of the characters
+ # 0-9 and a-f.
+ #
+ # The sid may be passed in a cookie from the client and as such
+ # should not be trusted. This is particularly important in
+ # FileSession, where the session filename is derived from the sid.
+ # A sid containing '/' or '.' characters could result in a directory
+ # traversal attack
+
+ return not not validate_sid_re.match(sid)
+
class BaseSession(dict):
def __init__(self, req, sid=None, secret=None, lock=1,
@@ -120,6 +149,14 @@
if cookies.has_key(session_cookie_name):
self._sid = cookies[session_cookie_name].value
+
+ if self._sid:
+ # Validate the sid *before* locking the session
+ # _check_sid will raise an apache.SERVER_RETURN exception
+ if not _check_sid(self._sid):
+ self._req.log_error("mod_python.Session warning: The session id contains invalid characters, valid characters are only 0-9 and a-f",
+ apache.APLOG_WARNING)
+ raise apache.SERVER_RETURN, apache.HTTP_INTERNAL_SERVER_ERROR
self.init_lock()
Modified: httpd/mod_python/branches/3.2.x/lib/python/mod_python/__init__.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/branches/3.2.x/lib/python/mod_python/__init__.py?rev=378945&r1=378944&r2=378945&view=diff
==============================================================================
--- httpd/mod_python/branches/3.2.x/lib/python/mod_python/__init__.py (original)
+++ httpd/mod_python/branches/3.2.x/lib/python/mod_python/__init__.py Sun Feb 19 11:51:17 2006
@@ -20,5 +20,5 @@
__all__ = ["apache", "cgihandler", "psp",
"publisher", "util", "python22"]
-version = "3.2.7"
+version = "3.2.8"
Modified: httpd/mod_python/branches/3.2.x/src/include/mpversion.h
URL: http://svn.apache.org/viewcvs/httpd/mod_python/branches/3.2.x/src/include/mpversion.h?rev=378945&r1=378944&r2=378945&view=diff
==============================================================================
--- httpd/mod_python/branches/3.2.x/src/include/mpversion.h (original)
+++ httpd/mod_python/branches/3.2.x/src/include/mpversion.h Sun Feb 19 11:51:17 2006
@@ -1,5 +1,5 @@
#define MPV_MAJOR 3
#define MPV_MINOR 2
-#define MPV_PATCH 7
-#define MPV_BUILD 20060202
-#define MPV_STRING "3.2.7"
+#define MPV_PATCH 8
+#define MPV_BUILD 20060219
+#define MPV_STRING "3.2.8"
Modified: httpd/mod_python/branches/3.2.x/test/test.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/branches/3.2.x/test/test.py?rev=378945&r1=378944&r2=378945&view=diff
==============================================================================
--- httpd/mod_python/branches/3.2.x/test/test.py (original)
+++ httpd/mod_python/branches/3.2.x/test/test.py Sun Feb 19 11:51:17 2006
@@ -1595,10 +1595,47 @@
response = conn.getresponse()
rsp = response.read()
conn.close()
-
if rsp != "test ok":
self.fail("session did not accept our cookie")
+ def test_Session_illegal_sid_conf(self):
+
+ c = VirtualHost("*",
+ ServerName("test_Session_Session"),
+ DocumentRoot(DOCUMENT_ROOT),
+ Directory(DOCUMENT_ROOT,
+ SetHandler("mod_python"),
+ PythonHandler("tests::Session_Session"),
+ PythonDebug("On")))
+ return str(c)
+
+ def test_Session_illegal_sid(self):
+
+ print "\n * Testing Session with illegal session id value"
+ bad_cookie = 'pysid=/path/traversal/attack/bad; path=/'
+ conn = httplib.HTTPConnection("127.0.0.1:%s" % PORT)
+ conn.putrequest("GET", "/tests.py", skip_host=1)
+ conn.putheader("Host", "test_Session_Session:%s" % PORT)
+ conn.putheader("Cookie", bad_cookie)
+ conn.endheaders()
+ response = conn.getresponse()
+ status = response.status
+ conn.close()
+ if status != 500:
+ self.fail("session accepted a sid with illegal characters")
+
+ bad_cookie = 'pysid=%s; path=/' % ('abcdef'*64)
+ conn = httplib.HTTPConnection("127.0.0.1:%s" % PORT)
+ conn.putrequest("GET", "/tests.py", skip_host=1)
+ conn.putheader("Host", "test_Session_Session:%s" % PORT)
+ conn.putheader("Cookie", bad_cookie)
+ conn.endheaders()
+ response = conn.getresponse()
+ status = response.status
+ conn.close()
+ if status != 500:
+ self.fail("session accepted a sid which is too long")
+
def test_publisher_conf(self):
c = VirtualHost("*",
ServerName("test_publisher"),
@@ -1970,6 +2007,7 @@
perRequestSuite.addTest(PerRequestTestCase("test_Cookie_Cookie"))
perRequestSuite.addTest(PerRequestTestCase("test_Cookie_MarshalCookie"))
perRequestSuite.addTest(PerRequestTestCase("test_Session_Session"))
+ perRequestSuite.addTest(PerRequestTestCase("test_Session_illegal_sid"))
perRequestSuite.addTest(PerRequestTestCase("test_interpreter_per_directive"))
perRequestSuite.addTest(PerRequestTestCase("test_interpreter_per_directory"))
perRequestSuite.addTest(PerRequestTestCase("test_publisher"))