[Checkins] SVN: zope.pluggableauth/trunk/ svn merge -r 120173:120176 svn+ssh://svn.zope.org/repos/main/zope.pluggableauth/branches/janjaapdriessen-camefrom-fix .
Jan-Wijbrand Kolman
janwijbrand at gmail.com
Tue Feb 8 03:53:11 EST 2011
Log message for revision 120186:
svn merge -r 120173:120176 svn+ssh://svn.zope.org/repos/main/zope.pluggableauth/branches/janjaapdriessen-camefrom-fix .
Changed:
U zope.pluggableauth/trunk/CHANGES.txt
U zope.pluggableauth/trunk/src/zope/pluggableauth/plugins/session.py
-=-
Modified: zope.pluggableauth/trunk/CHANGES.txt
===================================================================
--- zope.pluggableauth/trunk/CHANGES.txt 2011-02-07 16:24:47 UTC (rev 120185)
+++ zope.pluggableauth/trunk/CHANGES.txt 2011-02-08 08:53:10 UTC (rev 120186)
@@ -5,9 +5,10 @@
1.3 (unreleased)
----------------
-- Nothing changed yet.
+- As the camefrom information is most probably used for a redirect, require
+ it to be an absolute URL (see also
+ http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30).
-
1.2 (2010-12-16)
----------------
@@ -17,7 +18,6 @@
For example, you could use keas.kmi and encrypt the passwords of the
currently logged-in users so they don't appear in plain text in the ZODB.
-
1.1 (2010-10-18)
----------------
Modified: zope.pluggableauth/trunk/src/zope/pluggableauth/plugins/session.py
===================================================================
--- zope.pluggableauth/trunk/src/zope/pluggableauth/plugins/session.py 2011-02-07 16:24:47 UTC (rev 120185)
+++ zope.pluggableauth/trunk/src/zope/pluggableauth/plugins/session.py 2011-02-08 08:53:10 UTC (rev 120186)
@@ -261,7 +261,7 @@
>>> request.response.getStatus()
302
>>> request.response.getHeader('location')
- 'http://127.0.0.1/@@loginForm.html?camefrom=%2F'
+ 'http://127.0.0.1/@@loginForm.html?camefrom=http%3A%2F%2F127.0.0.1'
The plugin redirects to the page defined by the loginpagename
attribute:
@@ -270,7 +270,7 @@
>>> plugin.challenge(request)
True
>>> request.response.getHeader('location')
- 'http://127.0.0.1/@@mylogin.html?camefrom=%2F'
+ 'http://127.0.0.1/@@mylogin.html?camefrom=http%3A%2F%2F127.0.0.1'
It also provides the request URL as a 'camefrom' GET style parameter.
To illustrate, we'll pretend we've traversed a couple names:
@@ -292,11 +292,26 @@
We see the 'camefrom' points to the requested URL:
- >>> request.response.getHeader('location') # doctest: +ELLIPSIS
- '.../@@mylogin.html?camefrom=%2Ffoo%2Fbar%2Ffolder%2Fpage+1.html%3Fq%3Dvalue'
+ >>> request.response.getHeader('location')
+ 'http://127.0.0.1/@@mylogin.html?camefrom=http%3A%2F%2F127.0.0.1%2Ffoo%2Fbar%2Ffolder%2Fpage+1.html%3Fq%3Dvalue'
This can be used by the login form to redirect the user back to the
originating URL upon successful authentication.
+
+ Now that the 'camefrom' is an absolute URL, quickly demonstrate that
+ 'camefrom' information that inadvertently points to a different host,
+ will by default not be trusted in a redirect:
+
+ >>> camefrom = request.response.getHeader('location')
+ >>> request.response.redirect(camefrom)
+ 'http://127.0.0.1/@@mylogin.html?camefrom=http%3A%2F%2F127.0.0.1%2Ffoo%2Fbar%2Ffolder%2Fpage+1.html%3Fq%3Dvalue'
+ >>> suspicious_camefrom = 'http://example.com/foobar'
+ >>> request.response.redirect(suspicious_camefrom) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ ValueError: Untrusted redirect to host 'example.com:80' not allowed.
+
+
"""
if not IHTTPRequest.providedBy(request):
return False
@@ -308,7 +323,7 @@
# Better to add the query string, if present
query = request.get('QUERY_STRING')
- camefrom = '/'.join([request.getURL(path_only=True)] + stack)
+ camefrom = '/'.join([request.getURL()] + stack)
if query:
camefrom = camefrom + '?' + query
url = '%s/@@%s?%s' % (absoluteURL(site, request),
More information about the checkins
mailing list