示例#1
0
    def __call__(self, environ, start_response):
        '''
        This method is called for each request.  It looks for a user-supplied
        CSRF token in the GET/POST parameters, and compares it to the token
        attached to ``environ['repoze.who.identity']['_csrf_token']``.  If it
        does not match, or if a token is not provided, it will remove the
        user from the ``environ``, based on the ``clear_env`` setting.
        '''
        request = Request(environ)
        log.debug(
            b_('CSRFProtectionMiddleware(%(r_path)s)') %
            {'r_path': to_bytes(request.path)})

        token = environ.get('repoze.who.identity', {}).get(self.csrf_token_id)
        csrf_token = environ.get(self.token_env)

        if token and csrf_token and token == csrf_token:
            log.debug(b_('User supplied CSRF token matches environ!'))
        else:
            if not environ.get(self.auth_state):
                log.debug(b_('Clearing identity'))
                self._clean_environ(environ)
                if 'repoze.who.identity' not in environ:
                    environ['repoze.who.identity'] = Bunch()
                if 'repoze.who.logins' not in environ:
                    # For compatibility with friendlyform
                    environ['repoze.who.logins'] = 0
                if csrf_token:
                    log.warning(
                        b_('Invalid CSRF token.  User supplied'
                           ' (%(u_token)s) does not match what\'s in our'
                           ' environ (%(e_token)s)') % {
                               'u_token': to_bytes(csrf_token),
                               'e_token': to_bytes(token)
                           })

        response = request.get_response(self.application)

        if environ.get(self.auth_state):
            log.debug(b_('CSRF_AUTH_STATE; rewriting headers'))
            token = environ.get('repoze.who.identity', {})\
                    .get(self.csrf_token_id)

            loc = update_qs(response.location,
                            {self.csrf_token_id: str(token)})
            response.location = loc
            log.debug(
                b_('response.location = %(r_loc)s') %
                {'r_loc': to_bytes(response.location)})
            environ[self.auth_state] = None

        return response(environ, start_response)
示例#2
0
    def __call__(self, environ, start_response):
        '''
        This method is called for each request.  It looks for a user-supplied
        CSRF token in the GET/POST parameters, and compares it to the token
        attached to ``environ['repoze.who.identity']['_csrf_token']``.  If it
        does not match, or if a token is not provided, it will remove the
        user from the ``environ``, based on the ``clear_env`` setting.
        '''
        request = Request(environ)
        log.debug('CSRFProtectionMiddleware(%(r_path)s)' %
                  {'r_path': to_bytes(request.path)})

        token = environ.get('repoze.who.identity', {}).get(self.csrf_token_id)
        csrf_token = environ.get(self.token_env)

        if token and csrf_token and token == csrf_token:
            log.debug('User supplied CSRF token matches environ!')
        else:
            if not environ.get(self.auth_state):
                log.debug('Clearing identity')
                self._clean_environ(environ)
                if 'repoze.who.identity' not in environ:
                    environ['repoze.who.identity'] = Bunch()
                if 'repoze.who.logins' not in environ:
                    # For compatibility with friendlyform
                    environ['repoze.who.logins'] = 0
                if csrf_token:
                    log.warning('Invalid CSRF token.  User supplied'
                                ' (%(u_token)s) does not match what\'s in our'
                                ' environ (%(e_token)s)' %
                                {'u_token': to_bytes(csrf_token),
                                 'e_token': to_bytes(token)})

        response = request.get_response(self.application)

        if environ.get(self.auth_state):
            log.debug('CSRF_AUTH_STATE; rewriting headers')
            token = environ.get('repoze.who.identity', {})\
                           .get(self.csrf_token_id)

            loc = update_qs(
                response.location, {self.csrf_token_id: str(token)})
            response.location = loc
            log.debug('response.location = %(r_loc)s' %
                      {'r_loc': to_bytes(response.location)})
            environ[self.auth_state] = None

        return response(environ, start_response)
示例#3
0
    def add_metadata(self, environ, identity):
        request = Request(environ)
        log.debug(
            b_('CSRFMetadataProvider.add_metadata(%(r_path)s)') %
            {'r_path': to_bytes(request.path)})

        session_id = environ.get(self.auth_session_id)
        if not session_id:
            session_id = request.cookies.get(self.session_cookie)
        log.debug(b_('session_id = %(s_id)r') % {'s_id': to_bytes(session_id)})

        if session_id and session_id != 'Set-Cookie:':
            environ[self.auth_session_id] = session_id
            token = sha1(session_id).hexdigest()
            identity.update({self.csrf_token_id: token})
            log.debug(b_('Identity updated with CSRF token'))
            path = self.strip_script(environ, request.path)
            if path == self.login_handler:
                log.debug(b_('Setting CSRF_AUTH_STATE'))
                environ[self.auth_state] = True
                environ[self.token_env] = token
            else:
                environ[self.token_env] = self.extract_csrf_token(request)

            app = environ.get('repoze.who.application')
            if app:
                # This occurs during login in some application configurations
                if isinstance(app, HTTPFound) and environ.get(self.auth_state):
                    log.debug(
                        b_('Got HTTPFound(302) from'
                           ' repoze.who.application'))
                    # What possessed people to make this a string or
                    # a function?
                    location = app.location
                    if hasattr(location, '__call__'):
                        location = location()
                    loc = update_qs(location, {self.csrf_token_id: str(token)})

                    headers = app.headers.items()
                    replace_header(headers, 'location', loc)
                    app.headers = ResponseHeaders(headers)
                    log.debug(
                        b_('Altered headers: %(headers)s') %
                        {'headers': to_bytes(app.headers)})
        else:
            log.warning(
                b_('Invalid session cookie %(s_id)r, not setting CSRF'
                   ' token!') % {'s_id': to_bytes(session_id)})
示例#4
0
    def add_metadata(self, environ, identity):
        request = Request(environ)
        log.debug('CSRFMetadataProvider.add_metadata(%(r_path)s)'
                  % {'r_path': to_bytes(request.path)})

        session_id = environ.get(self.auth_session_id)
        if not session_id:
            session_id = request.cookies.get(self.session_cookie)
        log.debug('session_id = %(s_id)r' % {'s_id':
                                             to_bytes(session_id)})

        if session_id and session_id != 'Set-Cookie:':
            environ[self.auth_session_id] = session_id
            token = sha1(session_id).hexdigest()
            identity.update({self.csrf_token_id: token})
            log.debug('Identity updated with CSRF token')
            path = self.strip_script(environ, request.path)
            if path == self.login_handler:
                log.debug('Setting CSRF_AUTH_STATE')
                environ[self.auth_state] = True
                environ[self.token_env] = token
            else:
                environ[self.token_env] = self.extract_csrf_token(request)

            app = environ.get('repoze.who.application')
            if app:
                # This occurs during login in some application configurations
                if isinstance(app, HTTPFound) and environ.get(self.auth_state):
                    log.debug('Got HTTPFound(302) from'
                              ' repoze.who.application')
                    # What possessed people to make this a string or
                    # a function?
                    location = app.location
                    if hasattr(location, '__call__'):
                        location = location()
                    loc = update_qs(location, {self.csrf_token_id:
                                               str(token)})

                    headers = app.headers.items()
                    replace_header(headers, 'location', loc)
                    app.headers = ResponseHeaders(headers)
                    log.debug('Altered headers: %(headers)s' % {
                        'headers': to_bytes(app.headers)})
        else:
            log.warning('Invalid session cookie %(s_id)r, not setting CSRF'
                        ' token!' % {'s_id': to_bytes(session_id)})
示例#5
0
文件: csrf.py 项目: davidhrbac/cnucnu
    def add_metadata(self, environ, identity):
        request = Request(environ)
        log.debug(_('CSRFMetadataProvider.add_metadata(%(r_path)s)')
                % {'r_path': request.path})

        session_id = environ.get(self.auth_session_id)
        if not session_id:
            session_id = request.cookies.get(self.session_cookie)
        log.debug(_('session_id = %(s_id)r') % {'s_id': session_id})

        if session_id and session_id != 'Set-Cookie:':
            token = sha1(session_id).hexdigest()
            identity.update({self.csrf_token_id: token})
            log.debug(_('Identity updated with CSRF token'))
            path = self.strip_script(environ, request.path)
            if path == self.login_handler:
                log.debug(_('Setting CSRF_AUTH_STATE'))
                environ[self.auth_state] = True
                environ[self.token_env] = token
            else:
                environ[self.token_env] = self.extract_csrf_token(request)

            app = environ.get('repoze.who.application')
            if app:
                # This occurs during login in some application configurations
                if isinstance(app, HTTPFound) and environ.get(self.auth_state):
                    log.debug(_('Got HTTPFound(302) from'
                        ' repoze.who.application'))
                    loc = update_qs(app.location(), {self.csrf_token_id:
                        str(token)})

                    replace_header(app.headers, 'location', loc)
                    log.debug(_('Altered headers: %(headers)s') % {'headers':
                        str(app.headers)})
        else:
            log.warning(_('Invalid session cookie %(s_id)r, not setting CSRF'
                ' token!') % {'s_id': session_id})
示例#6
0
 def test_simple_without_overwrite_and_same(self):
     original = base + "?foo=yes"
     expected = base + "?foo=yes&foo=yes"
     params = dict(foo="yes")
     actual = update_qs(original, params, overwrite=False)
     self.assertEquals(actual, expected)
示例#7
0
 def test_simple_with_tuples(self):
     original = base
     expected = base + "?foo=yes"
     params = [('foo', 'yes')]
     actual = update_qs(original, params)
     self.assertEquals(actual, expected)
示例#8
0
 def test_simple_idempotence(self):
     original = base + "?foo=yes"
     expected = base + "?foo=yes"
     params = dict(foo="yes")
     actual = update_qs(original, params)
     self.assertEquals(actual, expected)
示例#9
0
 def test_simple_with_overwrite(self):
     original = base + "?foo=yes"
     expected = base + "?foo=no"
     params = dict(foo="no")
     actual = update_qs(original, params)
     self.assertEquals(actual, expected)
示例#10
0
 def test_simple_with_tuples(self):
     original = base
     expected = base + "?foo=yes"
     params = [('foo', 'yes')]
     actual = update_qs(original, params)
     self.assertEquals(actual, expected)
示例#11
0
 def test_simple_without_overwrite_and_same(self):
     original = base + "?foo=yes"
     expected = base + "?foo=yes&foo=yes"
     params = dict(foo="yes")
     actual = update_qs(original, params, overwrite=False)
     self.assertEquals(actual, expected)
示例#12
0
 def test_simple_with_overwrite(self):
     original = base + "?foo=yes"
     expected = base + "?foo=no"
     params = dict(foo="no")
     actual = update_qs(original, params)
     self.assertEquals(actual, expected)
示例#13
0
 def test_simple_idempotence(self):
     original = base + "?foo=yes"
     expected = base + "?foo=yes"
     params = dict(foo="yes")
     actual = update_qs(original, params)
     self.assertEquals(actual, expected)
示例#14
0
 def test_simple_add(self):
     original = base
     expected = base + "?foo=yes"
     params = dict(foo="yes")
     actual = update_qs(original, params)
     self.assertEqual(actual, expected)