一位网络安全专家最近检查了我的 Flask api,看看它有多脆弱,结果发现它非常脆弱。他能够检索我的烧瓶密钥,然后查看所有会话并以管理员身份登录以及他真正想做的任何其他事情。他能够充当管理员并获取我们所有用户的信息。
我的问题是他究竟是如何做到这一点的。我的 Flask 密钥作为环境变量存储在服务器托管服务中。我生成访问令牌的方式有问题吗?
以下是我的登录逻辑。请记住,我正在使用flask-jwt-extend。
@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
这是我的 config.py 文件的相关部分
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"
任何帮助都会很棒,因为这是一个相当严重的安全问题。谢谢!
这可能是由于服务器或应用程序存储位置所致。如果启用了 root 访问权限,您应该将其禁用。如果可能的话,您可以使用某种保管库,将敏感信息保存在那里。此外,您应该只接受 https 请求。如果可能的话使用容器。不要忘记对您的资源使用 @jwt_required() 。