Changeset - 04d2bcfbe7a6
[Not reviewed]
beta
0 1 0
Marcin Kuzminski - 13 years ago 2012-07-31 00:27:22
marcin@python-works.com
security fix, inspired by django security
announcement: https://www.djangoproject.com/weblog/2012/jul/30/security-releases-issued/
- filter out bad schemes and netloc differences
1 file changed with 14 insertions and 0 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/login.py
Show inline comments
 
@@ -17,24 +17,25 @@
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import logging
 
import formencode
 
import datetime
 
import urlparse
 

	
 
from formencode import htmlfill
 
from webob.exc import HTTPFound
 
from pylons.i18n.translation import _
 
from pylons.controllers.util import abort, redirect
 
from pylons import request, response, session, tmpl_context as c, url
 

	
 
import rhodecode.lib.helpers as h
 
from rhodecode.lib.auth import AuthUser, HasPermissionAnyDecorator
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.model.db import User
 
from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
 
@@ -87,24 +88,37 @@ class LoginController(BaseController):
 
                log.info('user %s is now authenticated and stored in '
 
                         'session, session attrs %s' % (username, cs))
 

	
 
                # dumps session attrs back to cookie
 
                session._update_cookie_out()
 

	
 
                # we set new cookie
 
                headers = None
 
                if session.request['set_cookie']:
 
                    # send set-cookie headers back to response to update cookie
 
                    headers = [('Set-Cookie', session.request['cookie_out'])]
 

	
 
                allowed_schemes = ['http', 'https', 'ftp']
 
                parsed = urlparse.urlparse(c.came_from)
 
                server_parsed = urlparse.urlparse(url.current())
 

	
 
                if parsed.scheme and parsed.scheme not in allowed_schemes:
 
                    log.error('Suspicious URL scheme detected %s for url %s' %
 
                              (parsed.scheme, parsed))
 
                    c.came_from = url('home')
 
                elif server_parsed.netloc != parsed.netloc:
 
                    log.error('Suspicious NETLOC detected %s for url %s'
 
                              'server url is: %s' %
 
                              (parsed.netloc, parsed, server_parsed))
 
                    c.came_from = url('home')
 
                if c.came_from:
 
                    raise HTTPFound(location=c.came_from, headers=headers)
 
                else:
 
                    raise HTTPFound(location=url('home'), headers=headers)
 

	
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                    render('/login.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
0 comments (0 inline, 0 general)