Flask Session
Flaskは、クッキーベースのセッション管理をしている
クッキーにセッションID以外の全てのセッション変数が保存される
もし、セッション変数に重要情報を保存していると、ユーザの利用する端末を介した重要情報漏えいリスクが生じる
サーバは、一定期間経過するまで、セッションIDを保持。
そのため、session.clear()してブラウザ上のクッキーが破棄された後も、ユーザが元のクッキーを別途コピーして保存していた場合に、サーバ側のセッションID保持期限が過ぎるまでの期間、コピーしたクッキを使ってWebサービスを継続利用できる
ということは、第三者も、クッキーを盗み出せば、サーバ側にセッションIDが保持されている間、例えユーザがログアウトした後であっても、ユーザ認証を経由せずに、ユーザになりすましてリプレイ攻撃をしたり、秘密情報を盗み出したり、その他、ユーザ認証等を必要としないアプリの様々なサービスを実行できたりする。
上記の問題を改善するために、サーバ上にセッションストレージを持つセッション管理用Flask拡張パッケージとして、Flask-Sessionを使ってみたところ、多少クセがあるものの、上記の問題を改善できた。
移行設定
session.permanent=True(Falseだと、ブラウザのclose時にセッションを閉じる。Trueの場合は)にして、PERMANENT_SESSION_LIFETIMEを利便性を犠牲にしない程度に短くしておく(このlifetimeは、期限が切れるまでにセッション変数が参照されると、その時点を起点として期限延長される。)
移行結果
ログアウト時にサーバ側で発行したsession.clear()により
サーバ上のセッション変数はすべて破棄される。なので、ログアウト後はクッキーを用いてユーザに成りすますことはできない。⇒期待通りの動作
クッキーはそのまま残る。
問題点
Flaskオリジナルのセッションと機能や設定方法が異なるが、ドキュメントの説明が不十分
クッキーに SameSite属性を付加できない。
上記PRを0.3.1に適用して、正常動作(SameSite付加したクッキーの送信)を確認した。ただし、いずれ、SameSite属性なしのものは SameSite=Laxが付加されるようなので、そのうち気にしなくてもよくなるかも。
Webのセッション管理仕様としての制限事項
セッションIDをクッキーとして保存し利用する点は、クッキーベースのセッション管理と変わりない。なので、ユーザのログイン中は、第三者によるなりすましのリスクが生じる。。
その他
session.permanent=Falseの場合(たぶん使わないと思うが)
SESSION_TYPE='sqlalchemy'で、DBにPostgreSQLを使用していた場合に、session.permanent=Falseだと、DB上のセッションの有効期限が Noneとなり、Flask-Session内でのsession処理がエラーを吐いた。(おそらく、Flask-Sessionは、SQLiteのように型に寛容なDBしか想定しておらず、日時以外の値を有効期限のカラムに保存しようとしてるんだと思う。SQLiteでも同様のエラー。)
SESSION_REFRESH_EACH_REQUESTを参照しない。なので、session.permanent=Trueにしたときのクッキーの有効期限の延長処理(クッキー送信処理)を抑止することができない。(Flask標準のSessionと同じ動作をさせるのは難しくないが、Flask-Sessionのコードにはなにかコメントがあった気がするので、一度目を通したほうがよいかも。)
Firefox (2020.7月現在の最新版の78.0.1)はサーバとクライアントの時計が30秒〜1分ほどずれている(クライアントの時計が進んでいる)場合に、クッキーを作らない。時刻合わせを気をつけた方がよい。