Affects Version/s: 3.2.10
Fix Version/s: None
The code used in the Session class for calculating the path (or domain) of the associated cookie is:
- the path where *Handler directive was specified
dirpath = self._req.hlist.directory
docroot = self._req.document_root()
c.path = dirpath[len(docroot):]
c.path = '/'
- Sometimes there is no path, e.g. when Location
- is used. When Alias or UserDir are used, then
- the path wouldn't match the URI. In those cases
- just default to '/'
if not c.path or not self._req.uri.startswith(c.path):
c.path = '/'
This code for calculating the path is sub optimal for a few reasons. The first is that it doesn't work for Location. Second is that it doesn't work for any case where the handler directory falls outside of the document root.
There are also problems in as much as it uses req.hlist.directory for trying to determine what the path below the document root may be, when in practice, the value of this isn't necessarily the directory that Python*Handler directive was specified for, as the handler could have been dynamically registered using req.add_handler() with the directory supplied explicitly, in which case req.hlist.directory is merely the first directory to look in for the Python module which implements the handler.
Most of the time the result will probably not match the post condition check and so '/' is always used, but at other times it may wrongly validate and be allowed when in fact it could be quite wrong.
With the addition of req.hlist.location, more appropriate code for determining the path would be:
path = '/'
context = req.hlist
context = context.parent
uri = posixpath.normpath(req.uri)
if req.uri[-1] == '/':
uri = uri + '/'
length = len(req.filename)
length -= len(context.directory) - 1
length += len(req.path_info or '')
path = uri[:-length] + '/'
path = context.location
The only problem with this code is that it relies on req.uri/req.filename/req.path_info not having been changed. The value of these could be changed either explicitly by a handler, or by modules such as mod_rewrite. The current mod_python.publisher code even modifies req.filename, although this is out of convenience rather than updating it to pass a modified value to later handler stages.
At this point, it is not really clear what should be done about the Session code for calculating the path. Ideally it should always equate to the leading part of the URL which targets the top most directory the handler has been specified for. Whether there is a way of meaningfully determining this in all cases is not clear.
As a result, best practice would always be to specify the application domain of the cookie for the session whenever sessions are used. In mod_python 3.3, this is done by using PythonOption to set the mod_python.session.application_domain property. If needing to be compatible with older versions of mod_python as well as mod_python 3.3, should instead use the older ApplicationPath property name with PythonOption.