【Spring MVC + Spring Security】CSRF攻撃の仕組みと対策方法

概要

CSRF(クロスサイトリクエストフォージェリ)攻撃の仕組みと対策方法についてまとめた。

 

前提

以下の記事の続きとなる。

あわせて読みたい

概要 基本的なセッションの運用方法についてまとめた。   前提 以下の記事の続きとなる。

 

CSRF攻撃の仕組み

CSRF(Cross-Site Request Forgery)とは、ユーザーがログイン中のWebサービスに対して、意図しない操作を強制的に実行させる攻撃手法のこと。
ユーザーの認証済みセッションを悪用してリクエストを送信させることで、本人の意思に反した処理を実行させる。

この攻撃は「ユーザー自身が操作したように見える」ため、サーバー側では正当なリクエストとして処理してしまう。
具体的には以下のようなステップで攻撃される。

ステップ 詳細 ポイント
①ログイン ユーザーが銀行サイトにログインする ログイン済みのセッションIDがCookieに保存される
②攻撃準備 フィッシング広告などが表示される(同じブラウザ上で別サイトを見ているときなど) 勝手に送金する送信フォームがJSで仕込まれている
③誘導 ユーザーが広告を踏んでしまう 裏で送金フォームが自動処理される
④自動送信 ブラウザはログイン済みのCookieを付与して送信する 同じブラウザだとCookieが共有されるため、ログイン済みのセッションが自動設定される
⑤誤認 サーバー側は本人による送信と誤認して処理する Cookieに設定されたセッション情報を照合した結果、本人とみなされる

 

 

CSRF攻撃の対策

この攻撃に対して、サーバー側ではCSRFトークン(ワンタイムトークン)を発行することで対策を行うことができる。
具体的には以下のような流れでCSRFトークンを活用する。

▲サーバー側で発行したCSRFトークンを再度送り返す仕組み

 

① クライアント側からリクエストする
② サーバー側でCSRFトークンを発行し、クライアントへのレスポンスに含める。
③ クライアントからの通信時(※状態を変更するPOST, PUT, DELTE通信)、このトークンをリクエストに含めて送信する。
④ サーバー側はトークンを検証し、一致する場合のみリクエストを受け付ける。

 

トークンの発行

Spring Securityでは、デフォルトでCSRFトークンが発行される。
そのためサーバー側でトークンを発行する特別な記述などは不要となる。

※以前の記事にてCSRFトークンを無効化する方法を紹介しているので、SecurityFilterChainに以下の実装がある場合は削除すること

http
// デフォルトのCSRF機能を有効にする
// .csrf(csrf -> csrf.disable())

 

参考

概要 自作ログイン画面を利用した、簡易的なログイン認証機能の利用方法についてまとめた。   前提 以下の記事の続きとなる。

 

トークンの設定

ビュー側にCSRFトークンを埋め込む。

 

login.jsp


<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>ログイン画面</title>
</head>
<body>
	<h2>ログイン</h2>
	<c:if test="${not empty param.logout}">
		<p>ログアウトしました</p>
	</c:if>

	<c:if test="${not empty SPRING_SECURITY_LAST_EXCEPTION}">
		<p>
			<c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
		</p>
	</c:if>
	
	<form action="${pageContext.request.contextPath}/authentication/process" method="post">
		<sec:csrfInput/>
		<label for="loginId">ログインID:</label>
		<input type="text" id="loginId" name="loginId" autofocus />
		<br />
		<label for="password">パスワード:</label>
		<input type="password" id="pass" name="pass" />
		<br />
		<input type="submit" value="ログイン" />
	</form>
	<br>
</body>
</html>

 

<%@ taglib prefix=”sec” uri=”http://www.springframework.org/security/tags” %>
<form action=”xxxx” method=”post“>
<sec:csrfInput/>

postフォーム配下に「<sec:csrfInput/>」を記述することで、以下のようなhidden属性のinputタグが展開され、サーバー側にトークンが送信される。

<input type="hidden" name="_csrf" value="サーバーから発行されたCSRFトークン">

 

 

まとめ

 

☑ CSRF攻撃とは、攻撃者が用意したページなどから正規サイトへ不正なリクエストを送信させる攻撃手法のこと

☑ 防衛策として、CSRFトークン(ワンタイムトークン)を活用する

☑ CSRFトークンは、リクエスト(POST, PUT, DELETE)通信時に、正規のユーザー操作であることを検証するためにサーバーへ送信される

 

スポンサーリンク