A cyber security specialist recently went through my Flask api to see how vulnerable it was and it turns out it was very vulnerable. He was able to retrieve my flask secret key and then view all the sessions and login as an admin and anything else he really wanted to do. He was able to act as admin and get information of all our users.
My question is how exactly he was able to do this. My flask secret key is stored as an environment variable in the server hosting service. Is it a problem with how im generating the access tokens?
The following is my login logic. Keep in mind I am using flask-jwt-extended.
@auth_bp.route("/flask/auth/login", methods=["POST"])
def login():
data, invalid_request = check_json_and_validate_schema(
request, login_user_schema)
if invalid_request:
return jsonify({"Error": invalid_request}), 422
email, password = (data["email"], data["password"])
email = email.lower()
user = User.query.filter_by(email=email).first()
if user is None:
return jsonify({"error": "user not found"}), 401
if not bcrypt.check_password_hash(user.password, password):
login_data = {}
login_data["user_id"] = user.user_id
login_data["is_successful"] = False
login_log = LoginLog(**login_data)
db.session.add(login_log)
db.session.commit()
return jsonify({"error": "incorrect email or password."}), 401
login_data = {}
login_data["user_id"] = user.user_id
login_data["is_successful"] = True
login_log = LoginLog(**login_data)
db.session.add(login_log)
db.session.commit()
access_token = create_access_token(identity=user.user_id)
refresh_token = create_refresh_token(identity=user.user_id)
resp = jsonify(
{
"Message": f"Successfully logged in basic user {user.first_name}",
"user": user.serialize(),
"email": user.email,
"watched_intro": user.watched_intro,
"access_token": access_token,
"refresh_token": refresh_token}
)
return resp, 200
And this is the relevant part of my config.py file
import os
from datetime import timedelta
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SQLALCHEMY_DATABASE_URI = "postgresql://{0}:{1}@{2}/{3}".format(
os.getenv("DB_USER"),
os.getenv("DB_PASS"),
os.getenv("DB_URL"),
os.getenv("DB_NAME"),
)
CSRF_ENABLED = True
SECRET_KEY = os.getenv("SECRET_KEY")
SQLALCHEMY_TRACK_MODIFICATIONS = True
JWT_ACCESS_TOKEN_EXPIRES = timedelta(days=100)
JWT_COOKIE_SECURE = True
JWT_COOKIE_SAMESITE = "None"
JWT_TOKEN_LOCATION = "headers"
JWT_CSRF_IN_COOKIES = True
JWT_COOKIE_CSRF_PROTECT = True
JWT_ACCESS_CSRF_HEADER_NAME = "X-Csrf-Token"
Any help would be amazing since this is a rather serious security issue. Thank you!