LaTeX957300 views
雑学1472593 views
高校日本史189857 views
ヒストリア284143 views
中学英語808712 views
Computer365120 views
小学算数1194618 views
中学理科1626207 views
教育148875 views
中学社会667106 views
Help
Tools

English

Flask のセッション Cookie に機密情報を入れてはいけない

Flask のデフォルトセッションはクライアント側の Cookie に保存される。署名により改ざんは検知できるが、内容は暗号化されていないため、機密情報を入れてはいけない。

Flask セッションの仕組み

Flask のセッションは itsdangerous ライブラリで署名されている。

from flask import Flask, session

app = Flask(__name__)
app.secret_key = 'your-secret-key'

@app.route('/login')
def login():
    session['user_id'] = 123
    session['role'] = 'admin'  # これは読める
    return 'Logged in'

ブラウザの開発者ツールで Cookie を確認すると、session という名前の値が見える。

セッション Cookie の中身を見る

セッション Cookie は Base64 エンコードされた JSON であり、簡単にデコードできる。

import base64

cookie = 'eyJ1c2VyX2lkIjoxMjMsInJvbGUiOiJhZG1pbiJ9...'
# ドットより前がペイロード
payload = cookie.split('.')[0]
# Base64 デコード
decoded = base64.urlsafe_b64decode(payload + '==')
print(decoded)  # b'{"user_id":123,"role":"admin"}'

このように、セッションに保存した内容は誰でも読める。

入れてはいけないもの

パスワードやパスワードハッシュ
クレジットカード情報
個人を特定できる機密情報(マイナンバーなど)
API キーやトークン

署名の役割

署名は改ざんを検知するためのものであり、秘匿のためではない。

# 攻撃者が role を admin に書き換えようとしても
# 署名が一致しないので Flask が拒否する

ただし、secret_key が漏洩すると攻撃者は有効な署名を生成できてしまう。secret_key は十分に複雑な値を設定し、絶対に外部に漏らさないこと。

安全な代替手段

機密情報はサーバーサイドに保存し、セッションには ID だけを入れる。

@app.route('/login')
def login():
    session['session_id'] = generate_session_id()
    # 機密情報は Redis やデータベースに保存
    redis.hset(f'session:{session_id}', 'credit_card', '****')
    return 'Logged in'

Flask-Session を使えば、セッション自体をサーバーサイドに保存できる。

from flask_session import Session

app.config['SESSION_TYPE'] = 'redis'
Session(app)

この設定では Cookie にはセッション ID のみが保存され、実際のデータは Redis に格納される。