Пример #1
0
def test_safe_str_cmp_no_builtin():
    import werkzeug.security as sec
    prev_value = sec._builtin_safe_str_cmp
    sec._builtin_safe_str_cmp = None
    assert safe_str_cmp('a', 'ab') is False

    assert safe_str_cmp('str', 'str') is True
    assert safe_str_cmp('str1', 'str2') is False
    sec._builtin_safe_str_cmp = prev_value
Пример #2
0
def test_safe_str_cmp_no_builtin():
    import werkzeug.security as sec

    prev_value = sec._builtin_safe_str_cmp
    sec._builtin_safe_str_cmp = None
    assert safe_str_cmp("a", "ab") is False

    assert safe_str_cmp("str", "str") is True
    assert safe_str_cmp("str1", "str2") is False
    sec._builtin_safe_str_cmp = prev_value
Пример #3
0
def upload_dance():
    if app.config['RG_VERIFY_ENDPOINT']:
        user_id, user_token = request.form['user_id'], request.form['user_token']
        check_token = hmac.new(app.config['RG_VERIFY_SECRET'], user_id, hashlib.sha1).hexdigest()
        if not safe_str_cmp(user_token, check_token):
            abort(403)

    gif = request.files['moves']
    gif_data = gif.read()
    if gif and check_gif(gif_data):
        dance_id = hashlib.sha1(gif_data).hexdigest()
        dance = {
            '_id': dance_id,
            'ts': time.time(),
            'ip': request.remote_addr,
            'ua': request.user_agent.string,
            'status': 'new',
        }
        if app.config['RG_VERIFY_ENDPOINT']:
            dance['rg_id'] = user_id
        g.db.save(dance)
        with open(os.path.join(app.config['UPLOAD_FOLDER'], dance_id + '.gif'), 'w') as out:
            out.write(gif_data)
        json_data = dance_json(dance)
        json_data['token'] = dance_owner_token(dance_id)
        return json.jsonify(json_data)
Пример #4
0
 def check_password_hash(self, password):
     if PYVER < 3 and isinstance(password, unicode):
         password = password.encode('u8')
     elif PYVER >= 3 and isinstance(password, bytes):
         password = password.decode('utf-8')
     password = str(password)
     return safe_str_cmp(bcrypt.hashpw(password, self.password), self.password)
Пример #5
0
def before_request():
    connect_db()

    if request.method not in ['GET', 'HEAD', 'OPTIONS']:
        if (not request.headers.get('X-CSRFT') or
                not session.get('csrft') or
                not safe_str_cmp(session['csrft'], request.headers['X-CSRFT'])):
            abort(400)

    g.is_reviewer = False
    auth = request.authorization
    if (auth and request.scheme == 'https' and
        safe_str_cmp(auth.username, app.config['REVIEWER_USERNAME'])):
        crypted = bcrypt.hashpw(auth.password, app.config['REVIEWER_PASSWORD'])
        if safe_str_cmp(crypted, app.config['REVIEWER_PASSWORD']):
            g.is_reviewer = True
Пример #6
0
    def check_password_hash(self, pw_hash, password):
        '''Tests a password hash against a candidate password. The candidate 
        password is first hashed and then subsequently compared in constant 
        time to the existing hash. This will either return `True` or `False`.

        Example usage of :class:`check_password_hash` would look something 
        like this::

            pw_hash = bcrypt.generate_password_hash('secret', 10)
            bcrypt.check_password_hash(pw_hash, 'secret') # returns True

        :param pw_hash: The hash to be compared against.
        :param password: The password to compare.
        '''

        # Python 3 unicode strings must be encoded as bytes before hashing.
        if PY3 and isinstance(pw_hash, bytes):
            pw_hash = pw_hash.decode('utf-8')

        if PY3 and isinstance(password, bytes):
            password = password.decode('utf-8')

        if not PY3 and isinstance(pw_hash, unicode):
            pw_hash = pw_hash.encode('utf-8')

        if not PY3 and isinstance(password, unicode):
            password = password.encode('utf-8')

        return safe_str_cmp(bcrypt.hashpw(password, pw_hash), pw_hash)
Пример #7
0
def add_message():
    try:
        token, uses = session.get('csrf', '').split(':', 1)
    except:
        flash('Whoa! Looks like there was a problem', 'error')
        return redirect(url_for('home'))
    else:
        _token = request.form.get('_token', '')
        _token, uses = _token.split(':', 1)
        if not safe_str_cmp(token, _token) or not int(uses) <= 10:
            flash('Looks like there was a problem', 'error')
            return redirect(url_for('home'))
        else:
            session['csrf'] = '{}:{}'.format(token, int(uses) + 1)
    
    msg = request.form.get('your-question')
    if msg is None or '' == msg:
        flash('Please ask a question', 'warning')
        return redirect(url_for('home'))
    
    count = g.redis.incr('question_counter')
    if 'messages' not in session:
        session['messages'] = [count]
    else:
        session['messages'].append(count)
    
    g.redis.set('message:{}'.format(count), msg)
    
    flash('Your question has been asked, just hang out here (or come back '
        'later for your answers')
    return redirect(url_for('listen'))
Пример #8
0
def confirm_reset_password_token(token):
    max_age_key = 'USERS_RESET_PASSWORD_TOKEN_MAX_AGE_IN_SECONDS'
    max_age = current_app.config[max_age_key]

    salt = current_app.config['USERS_RESET_PASSWORD_TOKEN_SALT']
    serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])

    user, data = None, None
    expired, invalid = False, False

    try:
        data = serializer.loads(
            token,
            max_age=max_age,
            salt=salt)
    except SignatureExpired:
        d, data = serializer.loads_unsafe(token, salt=salt)
        expired = True
    except (BadSignature, TypeError, ValueError):
        invalid = True

    if data:
        user = User.get(id=data[0])

    if not invalid and user and user.password:
        password_hash = hashlib.md5(user.password).hexdigest()
        if not safe_str_cmp(password_hash, data[1]):
            invalid = True

    expired = expired and (user is not None)

    logger.debug("reset password token confirmed?",
                 expired=expired, invalid=invalid, user=user, data=data)

    return expired, invalid, user, data
Пример #9
0
def add_response():
    try:
        token, uses = session.get('csrf', '').split(':', 1)
    except:
        flash('Whoa! Looks like there was a problem', 'error')
        return redirect(url_for('home'))
    else:
        _token = request.form.get('_token', '')
        _token, uses = _token.split(':', 1)
        if not safe_str_cmp(token, _token) or not int(uses) <= 10:
            flash('Looks like there was a problem', 'error')
            return redirect(url_for('home'))
        else:
            session['csrf'] = '{}:{}'.format(token, int(uses) + 1)
    
    qid = request.form.get('question', 0)
    resp = request.form.get('your-answer', '')
    if resp is None or '' == resp:
        flash('Whoa there, enter a response.', 'error')
        return redirect(url_for('question', id=qid))
    
    
    resp_count = g.redis.incr('response:{}:count'.format(qid))
    
    g.redis.set('response:{}:{}'.format(qid, resp_count), resp)
    flash('Your response has been added!')
    return redirect(url_for('question', id=qid))
def compare_password(hashed_password, password):
  if safe_str_cmp(bcrypt.hashpw(password.encode('utf-8'), hashed_password.encode('utf-8')), hashed_password):
    print "It matches"
    return True
  else:
    print "It does not match"
    return False
Пример #11
0
def remove_dance(dance_id):
    token = request.headers.get('X-Owner-Token')
    if not token or not safe_str_cmp(token, dance_owner_token(dance_id)):
        abort(403)
    dance = g.db[dance_id]
    dance['status'] = 'removed'
    g.db.save(dance)
    return '', 200
Пример #12
0
 def is_valid_password(self, password):
     """
     Check if given password is valid.
     """
     return safe_str_cmp(
         bcrypt.hashpw(password.encode('utf-8'), self.password_hash.encode('utf-8')),
         self.password_hash
     )
Пример #13
0
def bcrypt_check(data, password):
    import bcrypt
    try:
        encoded = data.encode('utf-8')
        encoded2 = bcrypt.hashpw(password.encode('utf-8'), encoded)
    except Exception:
        raise ValueError('Invalid hash format')
    return safe_str_cmp(encoded, encoded2)
Пример #14
0
def test_login(username, password):
    password = password.encode('utf-8')
    pw_hash = current_app.redis.get('user:'******':password')
    if not pw_hash:
        return False
    if not safe_str_cmp(hashlib.sha1(password).hexdigest(), pw_hash):
        return False
    return True
Пример #15
0
def _token_loader(token):
    try:
        data = _security.remember_token_serializer.loads(token)
        user = _security.datastore.find_user(id=data[0])
        if user and safe_str_cmp(md5(user.password), data[1]):
            return user
    except:
        pass
    return AnonymousUser()
Пример #16
0
def test_safe_str_cmp():
    assert safe_str_cmp("a", "a") is True
    assert safe_str_cmp(b"a", u"a") is True
    assert safe_str_cmp("a", "b") is False
    assert safe_str_cmp(b"aaa", "aa") is False
    assert safe_str_cmp(b"aaa", "bbb") is False
    assert safe_str_cmp(b"aaa", u"aaa") is True
    assert safe_str_cmp(u"aaa", u"aaa") is True
Пример #17
0
def test_safe_str_cmp():
    assert safe_str_cmp('a', 'a') is True
    assert safe_str_cmp(b'a', u'a') is True
    assert safe_str_cmp('a', 'b') is False
    assert safe_str_cmp(b'aaa', 'aa') is False
    assert safe_str_cmp(b'aaa', 'bbb') is False
    assert safe_str_cmp(b'aaa', u'aaa') is True
    assert safe_str_cmp(u'aaa', u'aaa') is True
Пример #18
0
def scrypt_check(data, password):
    try:
        salt, Nexp, r, p, keylen, h = data.split('$')
        Nexp = int(Nexp, 10)
        r = int(r, 10)
        p = int(p, 10)
        keylen = int(keylen, 10)
    except Exception:
        raise ValueError('Invalid hash format')
    return safe_str_cmp(h, _scrypt_password_hash(password, salt, Nexp, r, p, keylen))
Пример #19
0
    def unserialize(cls, string, secret_key):
        """Load the secure cookie from a serialized string.

        :param string: the cookie value to unserialize.
        :param secret_key: the secret key used to serialize the cookie.
        :return: a new :class:`SecureCookie`.
        """
        # explicitly convert it into a bytestring because python 2.6
        # no longer performs an implicit string conversion on hmac
        secret_key = str(secret_key)
        if isinstance(string, unicode):
            string = string.encode('utf-8', 'replace')
        try:
            base64_hash, data = string.split('?', 1)
        except (ValueError, IndexError):
            items = ()
        else:
            items = {}
            mac = hmac(secret_key, None, cls.hash_method)
            for item in data.split('&'):
                mac.update('|' + item)
                if not '=' in item:
                    items = None
                    break
                key, value = item.split('=', 1)
                # try to make the key a string
                key = url_unquote_plus(key)
                try:
                    key = str(key)
                except UnicodeError:
                    pass
                items[key] = value

            # no parsing error and the mac looks okay, we can now
            # sercurely unpickle our cookie.
            try:
                client_hash = base64_hash.decode('base64')
            except Exception:
                items = client_hash = None
            if items is not None and safe_str_cmp(client_hash, mac.digest()):
                try:
                    for key, value in items.iteritems():
                        items[key] = cls.unquote(value)
                except UnquoteError:
                    items = ()
                else:
                    if '_expires' in items:
                        if time() > items['_expires']:
                            items = ()
                        else:
                            del items['_expires']
            else:
                items = ()
        return cls(items, secret_key, False)
Пример #20
0
def authenticate(username, password):
    """
    Function that gets called when a user calls the /auth endpoint with their username and password
    :param username: User's username in string format.
    :param password: User's un-encrypted password in string format.
    :return: A user if authentication was successful, None otherwise.
    """

    user = UserModel.find_by_username(username)
    if user and safe_str_cmp(user.password, password):
        return user
Пример #21
0
def authenticate(username, password):
    """
    Checks if the user which is supplied in the /POST request exists
    :param username: username field in the JSON
    :param password: password field in the JSON
    :return: user_id
    """
    username_table = {u.username: u for u in users}
    user = username_table.get(username, None)
    if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
        return user
Пример #22
0
def pbkdf2_check(data, password):
    try:
        algorithm, iterations, salt, _ = data.split('$', 3)
        iterations = int(iterations)
    except Exception:
        raise ValueError('Invalid hash format')
    if algorithm != 'pbkdf2_sha256':
        raise ValueError('Unknown pbkdf2 algorithm variant')

    data2 = pbkdf2_encode(password, salt, iterations)
    return safe_str_cmp(data, data2)
Пример #23
0
def check_csrf_token():
    """Checks that token is correct, aborting if not"""
    if request.method in ("GET",): # not exhaustive list
        return
    token = request.form.get("csrf_token")
    if token is None:
        app.logger.warning("Expected CSRF Token: not present")
        abort(400)
    if not safe_str_cmp(token, csrf_token()):
        app.logger.warning("CSRF Token incorrect")
        abort(400)
Пример #24
0
    def unserialize(cls, string, secret_key):
        """Load the secure cookie from a serialized string.

        :param string: the cookie value to unserialize.
        :param secret_key: the secret key used to serialize the cookie.
        :return: a new :class:`SecureCookie`.
        """
        if isinstance(string, text_type):
            string = string.encode('utf-8', 'replace')
        if isinstance(secret_key, text_type):
            secret_key = secret_key.encode('utf-8', 'replace')
        try:
            base64_hash, data = string.split(b'?', 1)
        except (ValueError, IndexError):
            items = ()
        else:
            items = {}
            mac = hmac(secret_key, None, cls.hash_method)
            for item in data.split(b'&'):
                mac.update(b'|' + item)
                if not b'=' in item:
                    items = None
                    break
                key, value = item.split(b'=', 1)
                # try to make the key a string
                key = url_unquote_plus(key.decode('ascii'))
                try:
                    key = to_native(key)
                except UnicodeError:
                    pass
                items[key] = value

            # no parsing error and the mac looks okay, we can now
            # sercurely unpickle our cookie.
            try:
                client_hash = base64.b64decode(base64_hash)
            except TypeError:
                items = client_hash = None
            if items is not None and safe_str_cmp(client_hash, mac.digest()):
                try:
                    for key, value in iteritems(items):
                        items[key] = cls.unquote(value)
                except UnquoteError:
                    items = ()
                else:
                    if '_expires' in items:
                        if time() > items['_expires']:
                            items = ()
                        else:
                            del items['_expires']
            else:
                items = ()
        return cls(items, secret_key, False)
Пример #25
0
    def unserialize(cls, string, secret_key):
        """Load the secure cookie from a serialized string.

        :param string: the cookie value to unserialize.
        :param secret_key: the secret key used to serialize the cookie.
        :return: a new :class:`SecureCookie`.
        """
        if isinstance(string, unicode):
            string = string.encode("utf-8", "replace")
        if isinstance(secret_key, unicode):
            secret_key = secret_key.encode("utf-8", "replace")
        try:
            base64_hash, data = string.split("?", 1)
        except (ValueError, IndexError):
            items = ()
        else:
            items = {}
            mac = hmac(secret_key, None, cls.hash_method)
            for item in data.split("&"):
                mac.update("|" + item)
                if not "=" in item:
                    items = None
                    break
                key, value = item.split("=", 1)
                # try to make the key a string
                key = url_unquote_plus(key)
                try:
                    key = str(key)
                except UnicodeError:
                    pass
                items[key] = value

            # no parsing error and the mac looks okay, we can now
            # sercurely unpickle our cookie.
            try:
                client_hash = base64_hash.decode("base64")
            except Exception:
                items = client_hash = None
            if items is not None and safe_str_cmp(client_hash, mac.digest()):
                try:
                    for key, value in items.iteritems():
                        items[key] = cls.unquote(value)
                except UnquoteError:
                    items = ()
                else:
                    if "_expires" in items:
                        if time() > items["_expires"]:
                            items = ()
                        else:
                            del items["_expires"]
            else:
                items = ()
        return cls(items, secret_key, False)
Пример #26
0
def multi_constant_time_compare(value, expecteds):
    """
    Compares ``value`` against each of the strings in ``expecteds``, returns
    ``True`` if it is equal to any of them, and ``False`` otherwise.

    The amount of time this takes to execute is independent of how similar
    ``value`` is to the items in ``expecteds``.
    """
    found = 0
    for expected in expecteds:
        found |= safe_str_cmp(value, expected)
    return bool(found)
Пример #27
0
def show_settings():
    if request.method == "POST":
        if not g.user.check_password(request.form['old_password']):
            flash('Invalid current password.', 'error')
        elif not safe_str_cmp(request.form['new_password'], request.form['new_password_confirm']):
            flash('New password mismatch. Make sure you type the password correctly on both fields.', 'error')
        else:
            g.user.set_password(request.form['new_password'])
            g.db.commit()
            flash('Password changed.', 'success')

    return render_template('settings.html', user=g.user)
Пример #28
0
 def check_password(self, password):
     """Check the parameter `password` for a match with the user's
     password"""
     if self.password.startswith("pbkdf2"):
         return check_password_hash(self.password, password)
     else:
         # handle scuttle passwords (sha1) and migrate if correct
         rv = safe_str_cmp(self.password, hashlib.sha1(password).hexdigest())
         if rv is True:
             self.set_password(password)
             db.Session.commit()
         return rv
Пример #29
0
def password_login(id_type, identifier, password, pg=utils.postgres):
    """
    Attempts to log in using (`identifier`, `password`)

    `id_type` must be either 'user_id' or 'email'

    Returns the user, or raises one of :exc:`ShouldUseRaven`, 
    :exc:`EmailNotFound`, :exc:`BadPassword` or :exc:`UserDisabled`.
    """

    assert id_type in ("user_id", "email")

    # the schema guarantees us that raven users only have cam emails
    if id_type == "email":
        identifier = identifier.lower()
        if identifier.endswith("@cam.ac.uk"):
            raise ShouldUseRaven(identifier)

    query = "SELECT * FROM users WHERE {0} = %s".format(id_type)

    with pg.cursor(True) as cur:
        cur.execute(query, (identifier, ))
        assert cur.rowcount in (0, 1)
        if cur.rowcount == 1:
            user = cur.fetchone()
        else:
            assert id_type != "user_id" # this shouldn't happen
            logger.info("password login failed - bad %s %r",
                        id_type, identifier)
            raise EmailNotFound(identifier)

    if user["user_type"] == 'raven':
        logger.warning("password login attempted on raven user %s (%s)",
                       user["crsid"], user["user_id"])
        raise ShouldUseRaven(user["email"])
    elif user["user_type"] != 'password':
        logger.warning("password login attempted on non password user %s",
                       user["user_id"])
        raise WrongUserType(user["user_type"], 'password')

    if not user["enable_login"]:
        logger.warning("password login attempted while disabled - "
                       "user %s", user["user_id"])
        raise UserDisabled(user["user_id"])

    compare = bcrypt.hashpw(password, user["password_bcrypt"])
    if safe_str_cmp(user["password_bcrypt"], compare):
        logger.info("good password for user %s", user["user_id"])
        return user
    else:
        logger.info("bad password for user %s", user["user_id"])
        raise BadPassword(user["user_id"])
Пример #30
0
def decode_cookie(cookie):
    """ decode cookies managed by flask.ext.login """

    from router import SECRET_KEY
    try:
        payload, digest = cookie.rsplit(u'|', 1)
        if hasattr(digest, 'decode'):
            digest = digest.decode('ascii')
    except ValueError:
        return

    if safe_str_cmp(_cookie_digest(payload, SECRET_KEY), digest):
        return payload
Пример #31
0
def authenticate(username, password):
    user = UserModel.find_by_username(
        username
    )  # if there is not a username with username will return None
    if user and safe_str_cmp(user.password, password):
        return user
Пример #32
0
 def authenticate(self, username, password):
     user = self.usernameTable.get(username, None)
     if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
         return user
Пример #33
0
    def validate(self):
        '''
        Validates a CSRF token for the current request.

        If CSRF token is invalid, stops execution and sends a Forbidden error
        response to the client. Can be used in combination with :class:`exempt`
        to programmatically enable CSRF protection per request.

        Example usage of :class:`validate` might look something
        like::

            csrf = SeaSurf(app)

            @csrf.exempt
            @app.route('/sometimes_requires_csrf')
            def sometimes_requires_csrf():
                if not oauth_request():
                    # validate csrf unless this is an OAuth request
                    csrf.validate()
                return render_template('sometimes_requires_csrf.html')
        '''

        if not has_request_context():
            raise Forbidden(description=REASON_NO_REQUEST)

        # Tell _after_request to still set the CSRF token cookie when this
        # view was exemp, but validate was called manually in the view
        g.csrf_validation_checked = True

        server_csrf_token = session.get(self._csrf_name, None)

        if request.is_secure and self._check_referer:
            referer = request.headers.get('Referer')
            if referer is None:
                error = (REASON_NO_REFERER, request.path)
                error = u'Forbidden ({0}): {1}'.format(*error)
                current_app.logger.warning(error)
                raise Forbidden(description=REASON_NO_REFERER)

            # By setting the Access-Control-Allow-Origin header, browsers
            # will let you send cross-domain AJAX requests so if there is
            # an Origin header, the browser has already decided that it
            # trusts this domain otherwise it would have blocked the
            # request before it got here.
            allowed_referer = request.headers.get('Origin') or request.url_root
            if not _same_origin(referer, allowed_referer):
                error = REASON_BAD_REFERER.format(referer, allowed_referer)
                description = error
                error = (error, request.path)
                error = u'Forbidden ({0}): {1}'.format(*error)
                current_app.logger.warning(error)
                raise Forbidden(description=description)

        request_csrf_token = request.form.get(self._csrf_name, '')
        if not request_csrf_token:
            # Check to see if the data is being sent as JSON
            try:
                if hasattr(request, 'json') and request.json:
                    request_csrf_token = request.json.get(self._csrf_name, '')

            # Except Attribute error if JSON data is a list
            except (BadRequest, AttributeError):
                pass

        if not request_csrf_token:
            # As per the Django middleware, this makes AJAX easier and
            # PUT and DELETE possible.
            request_csrf_token = request.headers.get(self._csrf_header_name,
                                                     '')

        some_none = None in (request_csrf_token, server_csrf_token)
        if some_none or not safe_str_cmp(request_csrf_token,
                                         server_csrf_token):
            error = (REASON_BAD_TOKEN, request.path)
            error = u'Forbidden ({0}): {1}'.format(*error)
            current_app.logger.warning(error)
            raise Forbidden(description=REASON_BAD_TOKEN)
Пример #34
0
def authenticate(email_address, password):
    user = UserModel.find_by_email_address(email_address)
    if user and safe_str_cmp(user.password, password):
        return user
Пример #35
0
def authenticate(username, password):
    user = UserRepository.getByUsername(username)
    if user and safe_str_cmp(user.password, password):
        return user
Пример #36
0
def authenticate(username, password):
    user = User.objects(username=username).first()
    if user and safe_str_cmp(user.password.encode('utf-8'),
                             password.encode('utf-8')):
        return user
Пример #37
0
def authenticate(username: str, password: str) -> dict:
    user = User.find_by_username(username)
    if user and safe_str_cmp(user.password, password):
        return user