def generate_csrf(secret_key=None, time_limit=None): """Generate csrf token code. :param secret_key: A secret key for mixing in the token, default is Flask.secret_key. :param time_limit: Token valid in the time limit, default is 3600s. """ if not secret_key: secret_key = flask.current_app.config['SECRET_KEY'] if not secret_key: raise ValueError('Must provide secret_key to use csrf.') if time_limit is None: time_limit = flask.current_app.config['CSRF_TOKEN_TIME_LIMIT'] if 'csrf_token' not in flask.session: flask.session['csrf_token'] = hashlib.sha1(os.urandom(64)).hexdigest() if time_limit: expires = int(time.time() + time_limit) csrf_build = '%s%s' % (flask.session['csrf_token'], expires) else: expires = '' csrf_build = flask.session['csrf_token'] hmac_csrf = hmac.new( _compat.to_bytes(secret_key), _compat.to_bytes(csrf_build), digestmod=hashlib.sha1 ).hexdigest() return '%s##%s' % (expires, hmac_csrf)
def validate_csrf(data, secret_key=None, time_limit=None): """Check if the given data is a valid csrf token. :param data: The csrf token value to be checked. :param secret_key: A secret key for mixing in the token, default is Flask.secret_key. :param time_limit: Check if the csrf token is expired. default is True. """ if not data or '##' not in data: return False expires, hmac_csrf = data.split('##', 1) if time_limit is None: time_limit = flask.current_app.config['CSRF_TOKEN_TIME_LIMIT'] if time_limit: try: expires = int(expires) except ValueError: return False now = int(time.time()) if now > expires: return False if not secret_key: secret_key = flask.current_app.config['SECRET_KEY'] if not secret_key: raise ValueError('Must provide secret_key to use csrf.') if 'csrf_token' not in flask.session: return False csrf_build = '%s%s' % (flask.session['csrf_token'], expires) hmac_compare = hmac.new( _compat.to_bytes(secret_key), _compat.to_bytes(csrf_build), digestmod=hashlib.sha1 ).hexdigest() return werkzeug.security.safe_str_cmp(hmac_compare, hmac_csrf)