CSRFとは
- クロスサイトリクエストフォージェリ(CrossSiteRequestForgeries)
- ユーザーが意図しないリクエストをWebサイトに送るという攻撃
- ex:例えば、抽選で2億円が当たるというサイトを見つけました
- そのサイトには個人情報の入力が必要と書いていて。。
- 個人情報を入力してしまって、**"応募"**のボタンを押すと、
- そのユーザー情報で、別のWebサイトにアクセスさせて、高い物を購入させる
- といった攻撃です。。💀😱
- ex:例えば、抽選で2億円が当たるというサイトを見つけました
トークン
- これを防ぐため、Springで作ったWebサイトからは、トークン(ランダムな文字列)をパラメーターに加えてサーバーにリクエストするようにします
- トークン無しでリクエストを送ると、外部からのリクエストと判断できるため、Springはリクエストを拒否します
- 一方GETメソッドで画面を表示する場合には、トークンをパラメーターに含める必要はありません。
- Springセキュリティでは、CSRF対策がデフォルトで有効になっています
ログイン画面にトークンをパラメーターに含める
- ログイン画面のhtmlで、CSRF対策用トークンをパラメーターに含める
login.html
<!-- CSRF対策用トークン -->
<input type="hidden"
th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
CSRF対策用トークン
- 上記のように
hidden
でCSRF対策用のトークンをサーバーに送ります - CSRF対策を有効にしている場合、フォームを使っている画面では上記のコードを追加しないと、Springが何も応答しないです
- formタグを使用している画面は他にもありますが、CSRF対策用のトークンを送らなくても動作する。
- 実は、CSRF対策用のトークンを送らなくても、タイムリーフが自動でトークンを追加してくれるのです🌟
-
th:action
属性を使っていると、タイムリーフが自動追加してくれるが、- 以下のログイン画面ではformタグ内にaction属性を使っているので、自分でトークン追加しました!
-
- 基本はth:action属性を使えばOK!
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"></meta>
<!-- Bootstrapの設定 -->
<link th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}" rel="stylesheet"></link>
<script th:src="@{/webjars/jquery/1.11.1/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js}"></script>
<title>Login</title>
</head>
<body class="text-center">
<h1>Login</h1>
<form method="post" action="/login">
<!-- エラーメッセージ -->
<p th:if="${session['SPRING_SECURITY_LAST_EXCEPTION']} != null"
th:text="${session['SPRING_SECURITY_LAST_EXCEPTION'].message}"
class="text-danger">
ログインエラーメッセージ
</p>
<!-- ユーザーID -->
<label>ユーザーID</label>
<input type="text" name="userId" /><br/>
<br />
<!-- パスワード -->
<label>パスワード</label>
<input type="password" name="password" /><br/>
<br />
<!-- ログインボタン -->
<button class="btn btn-primary" type="submit">ログイン</button>
<!-- CSRF対策用トークン -->
<input type="hidden"
th:name="${_csrf.parameterName}"
th:value="${_csrf.token}" />
</form>
<br />
<!-- ユーザー登録画面へのリンク -->
<a th:href="@{'/signup'}">ユーザー新規登録はこちら</a>
</body>
</html>
ログインできることを確認!
- http://localhost:8080/login
- OKですね★