はじめに
この実験では、Flask を使って Web アプリケーションを開発する際の重要なセキュリティに関する考慮事項を探ります。クロスサイトスクリプティング (XSS)、クロスサイトリクエストフォージェリ (CSRF)、JSON セキュリティ、セキュリティヘッダー、およびセキュアなクッキーオプションなどのトピックを扱います。これらの手順に従うことで、Flask アプリケーションのセキュリティを強化する方法を学びます。
注:コードファイルは自分で作成し、環境で実行する必要があります。Web 5000 で Flask サービスの状態をプレビューできます。
クロスサイトスクリプティング (XSS)
クロスサイトスクリプティング (XSS) は、攻撃者がユーザーが閲覧する Web ページに悪意のあるスクリプトを注入できる脆弱性です。Flask で XSS 攻撃を防止するには、次のガイドラインに従います。
- 常にテキストをエスケープして、任意の HTML タグの含まれないようにします。
- Jinja2 テンプレートの助けを借りずに HTML を生成する際は注意してください。
Markupクラスを使用して、ユーザーが送信したデータをエスケープします。- アップロードされたファイルから HTML またはテキストファイルを送信しないでください。
サンプルコード:
## app.py
from flask import Flask, render_template_string, Markup
app = Flask(__name__)
@app.route('/')
def index():
value = '<script>alert("XSS Attack")</script>'
safe_value = Markup.escape(value)
return render_template_string('<input value="{{ value }}">', value=safe_value)
コードを実行するには、app.py という名前のファイルに保存し、flask run コマンドを実行します。
クロスサイトリクエストフォージェリ (CSRF)
クロスサイトリクエストフォージェリ (CSRF) は、ユーザーに対してウェブサイト上で意図しない操作を実行させる攻撃です。Flask で CSRF 攻撃を防止するには、次のガイドラインに従います。
- サーバーコンテンツを変更する要求を検証するために、ワンタイムトークンを使用します。
- トークンをクッキーに保存し、フォームデータとともに送信します。
- サーバーで受け取ったトークンと、クッキーに保存されたトークンを比較します。
サンプルコード:
## app.py
from flask import Flask, request, session, redirect, url_for
app = Flask(__name__)
app.secret_key = 'secret_key'
@app.route('/')
def index():
return render_template('index.html')
@app.route('/delete', methods=['POST'])
def delete_user():
if request.method == 'POST':
token = request.form.get('token')
if token and token == session.get('csrf_token'):
## Delete user profile
return redirect(url_for('index'))
return 'Invalid request'
if __name__ == '__main__':
app.run()
コードを実行するには、app.py という名前のファイルに保存し、flask run コマンドを実行します。
JSON セキュリティ
Flask では、JSON 応答のセキュリティを確保することが重要です。Flask 0.10 以前のバージョンでは、セキュリティ上の脆弱性のため、最上位の配列は JSON にシリアライズされませんでした。ただし、この動作は変更され、現在では最上位の配列がシリアライズされます。このセキュリティ向上の恩恵を受けるために、最新バージョンの Flask を使用することをお勧めします。
セキュリティヘッダー
ブラウザは、セキュリティを制御するためにさまざまな応答ヘッダーを認識します。Flask アプリケーションでは、次のセキュリティヘッダーを見直して使用することをお勧めします。
- HTTP Strict Transport Security (HSTS):ブラウザに対してすべての HTTP 要求を HTTPS に変換するように指示します。
- Content Security Policy (CSP):さまざまな種類のリソースをどこから読み込むことができるかを指定します。
- X-Content-Type-Options:ブラウザに応答コンテンツタイプを尊重するように強制します。
- X-Frame-Options:外部サイトが iframe であなたのサイトを埋め込むのを防ぎます。
Flask アプリケーションで HTTPS とセキュリティヘッダーを管理するには、Flask-Talisman 拡張機能を使用できます。
Set-Cookie オプション
Flask でクッキーを設定する際には、機密データを保護するためのセキュリティオプションを考慮することが重要です。推奨されるオプションのいくつかは以下の通りです。
- Secure:クッキーを HTTPS トラフィックに限定します。
- HttpOnly:クッキーの内容を JavaScript で読み取られることから保護します。
- SameSite:外部サイトからの要求でクッキーがどのように送信されるかを制限します。
サンプルコード:
## app.py
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/')
def index():
response = make_response('Hello, world!')
response.set_cookie('username', 'flask', secure=True, httponly=True, samesite='Lax')
return response
if __name__ == '__main__':
app.run()
コードを実行するには、app.py という名前のファイルに保存し、flask run コマンドを実行します。
HTTP パブリックキーピニング (HPKP)
HTTP パブリックキーピニング (HPKP) は、ブラウザに対して特定の証明書キーのみを使用してサーバーとの認証を行うセキュリティ機能です。これによりセキュリティを向上させることができますが、誤って設定またはアップグレードした場合には解除するのも困難です。HPKP の使用には十分に注意し、適切な設定を行うことをお勧めします。
まとめ
この実験では、Flask を使って Web アプリケーションを開発する際の重要なセキュリティに関する考慮事項を探りました。クロスサイトスクリプティング (XSS) やクロスサイトリクエストフォージェリ (CSRF) 攻撃を防止するための対策、JSON 応答のセキュリティ化、セキュリティヘッダーとクッキーオプションの設定について説明しました。これらのセキュリティ対策を守ることで、Flask アプリケーションのセキュリティを向上させ、潜在的な脆弱性からユーザーデータを保護することができます。