Flask-Login:防止 cookie 重用缺陷

Flask-Login : Prevent cookie reuse flaw

当一位朋友告诉我我的网站上存在安全漏洞时,我正在使用 Flask 开发 Web 应用程序。事实上,如果他在登录时转储浏览器的 cookie,注销,然后粘贴回相同的 cookie,就好像他从未注销过一样。事实上,这不是预期的行为。当用户注销时,cookie 应该失效,不能再使用。

现在我有一个用户模型,存储在数据库中。在这种情况下应该使用什么技术?以前有人遇到过同样的问题吗?更重要的是,我如何才能将这种安全性集成到我的网站上,而不必重写每个视图来检查令牌或类似的东西?

这是应用程序初始化。

# App initialization
app = Flask(__name__)
app.config.from_object('config')
app.wsgi_app = ProxyFix(app.wsgi_app)

# Database Setup
db = SQLAlchemy(app)

# Login Manager Setup
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'index'
login_manager.session_protection = 'strong'

这是我目前使用的用户模型。

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True)
    password = db.Column(db.String(54))
    superuser = db.Column(db.Boolean())
    active = db.Column(db.Boolean())
    register_date = db.Column(db.DateTime())
    last_login = db.Column(db.DateTime())

请注意,我删除了与此问题无关的方法和附加字段。

您可以将 Flask-Login 的安全级别设置为 "strong" - 这会增加对会话有效性的额外检查,并在发现标识符不匹配时删除整个会话。

https://flask-login.readthedocs.org/en/latest/

会话保护

login_manager.session_protection = "strong"

原因是 flask-login 接受了请求中的会话 cookie,因为它实际上是一个有效的会话 cookie,即使在用户将其删除并再次发送后也是如此。我同意,它 不应该 那样做,但它确实如此。如果用户更改密码,实际上会发生同样的事情,旧的 cookie 仍然有效,因为 flask-login 的 default 行为不是在会话 cookie 中使用用户密码。有一篇很好的文章 here

简而言之,使用 @login_manager.token_loader 并加载由基于用户密码哈希的加密签名密钥创建的会话令牌。正如所讨论的 here,这实际上是 flask-login 推荐的。您可以使用 werkzeug.itsdangerous.URLSafeTimedSerializer 到 load/create 令牌。

flask-login 的文档应该更清楚地反映这种行为,否则只能强制使用更强的标记作为默认行为。