CSRF Protection の有効化
SonarQube の第2のハイリスク クロスサイトリクエストフォージェリ について見ていきます。

CSRF により、攻撃者は、他の認証されたユーザーがクリックする可能性のあるリクエスト(資金送金)を偽造し、不正なアクションを実行させることができます。この種の攻撃を防ぐ1つの方法は、シンクロナイザトークンパターン、またはCSRFトークンと呼ばれます。CSRF トークンはバックエンドによって生成される一意の値で、HTML フォームに含まれ、入力の有効性に署名するために使用されます。
SonarQube は、それを防ぐ方法に関するいくつかの提案も提供しています。少し下にスクロールすると、FlaskでCSRF保護を実装する方法の例があります。

これが最初のコードセキュリティ修正になります。AWS Cloud9 に行って、コードを編集しましょう。
修正にはFlaskの CSRFソリューション を使用します。flask-app フォルダの下に、app.py ファイルを編集し、次のコード行を追加してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
import os
from flask import Flask
from pages import (
index,
about,
a1,
a2,
a3,
a5,
a6,
a7,
a9
)
import models
from flask_wtf.csrf import CSRFProtect
### Initialize App
app = Flask(__name__)
app.url_map.strict_slashes = False
### Enable CSRF
app.config['SECRET_KEY'] = os.urandom(32)
csrf = CSRFProtect()
csrf.init_app(app)
### Register blueprints
app.register_blueprint(index.bp)
app.register_blueprint(about.bp, url_prefix="/about")
app.register_blueprint(a1.bp, url_prefix="/owasp")
app.register_blueprint(a2.bp, url_prefix="/owasp")
app.register_blueprint(a3.bp, url_prefix="/owasp")
app.register_blueprint(a5.bp, url_prefix="/owasp")
app.register_blueprint(a6.bp, url_prefix="/owasp")
app.register_blueprint(a7.bp, url_prefix="/owasp")
app.register_blueprint(a9.bp, url_prefix="/owasp")
### Configure database
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///user.db"
models.db.init_app(app)
models.db.app = app
models.bootstrap()
|
app.py を保存します。先ほど追加した強調表示されたコード行は、Flask の CSRF 保護ライブラリをインポートし、アプリケーションにアタッチします。CsrfProtect トークンを生成して安全に署名するには、SECRET_KEY が必要です。わかりやすくするために、Web アプリケーションのインスタンスが 1 つしかないため、ランダムな値を使用しています。スケールさせていくユースケースの場合、この SECRET_KEY を各 Web アプリケーションインスタンス間で共有し、安全な方法で保存する必要があります (AWS シークレットマネージャー などを使用します)。
CSRF Protection の追加コードでは十分ではありません。保護したい HTML フォームに CSRF トークンを含めるように HTML テンプレートを更新する必要があります。templates/a2.html と templates/a5.html でこれを行う必要があります。これらのページは、ユーザーがログインするたびにブラウザクッキーを設定するためです。templates/a2.htmlを編集し、コードを次のように置き換えます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<!DOCTYPE html>
<html>
{% include "head.html" %}
<body>
<main>
{% include "navbar.html" %}
<div class="container col-xl-10 col-xxl-8 px-4 py-5">
<div class="row align-items-center g-lg-5 py-5">
<div class="col-lg-7 text-center text-lg-start">
<h1 class="display-4 fw-bold lh-1 mb-3">A2: Broken Authentication</h1>
<p>Application functions related to authentication and session management are often implemented incorrectly, allowing attackers to compromise passwords, keys, or session tokens, or to exploit other implementation flaws to assume other users’ identities temporarily or permanently.</p>
</div>
<div class="col-md-10 mx-auto col-lg-5">
<form class="p-4 p-md-5 border rounded-3 bg-light" action="/owasp/A2/auth" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput" name="username">
<label for="floatingInput">Username</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control" id="floatingPassword" name="password">
<label for="floatingPassword">Password</label>
</div>
<div class="checkbox mb-3">
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Login</button>
<hr class="my-4">
</form>
</div>
</div>
</div>
</main>
</body>
</html>
|
上の強調表示された行は、HTMLが生成されるたびに一意のhiddenパラメータをフォームに追加しています。このトークンは、入力を検証するためにバックエンドに送信されます。templates/a5/htmlでも同様に編集します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<!DOCTYPE html>
<html>
{% include "head.html" %}
<body>
<main>
{% include "navbar.html" %}
<div class="container col-xl-10 col-xxl-8 px-4 py-5">
<div class="row align-items-center g-lg-5 py-5">
<div class="col-lg-7 text-center text-lg-start">
<h1 class="display-4 fw-bold lh-1 mb-3">A5: Broken Access Control</h1>
<p>Restrictions on what authenticated users are allowed to do are often not properly enforced. Attackers can exploit these flaws to access unauthorized functionality and/or data, such as access other users’ accounts, view sensitive files, modify other users’ data, change access rights, etc.</p>
</div>
<div class="col-md-10 mx-auto col-lg-5">
<form class="p-4 p-md-5 border rounded-3 bg-light" action="/owasp/A5/auth" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput" name="username">
<label for="floatingInput">Username</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control" id="floatingPassword" name="password">
<label for="floatingPassword">Password</label>
</div>
<div class="checkbox mb-3">
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Login</button>
<hr class="my-4">
</form>
</div>
</div>
</div>
</main>
</body>
</html>
|
保存して、次のセキュリティ修正のセットに進みましょう。