1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BladeからVueに移行した時に気をつけるCSRF

Posted at

はじめに

Laravelで開発をしていると、Bladeテンプレートでは@csrf{{ csrf_token() }}を埋め込むのが当たり前ですが、Vueフロントエンドで実装した時に「そういえばCSRF対策はどうなっている?」となったので調べて整理した備忘録です。

CSRFとは?

CSRF(Cross-Site Request Forgery) は、ユーザーの権限を悪用して「意図しないリクエスト」を送らせる攻撃です。

前提条件

  1. ユーザーがすでにログインしてセッションが有効
  2. 攻撃者が罠ページやメールを用意
  3. ユーザーが罠ページを踏むと、勝手にリクエストが送信される

具体例:銀行の送金操作

正常なリクエスト

POST https://bank.example.com/transfer
Content-Type: appication/x-www-form-urlencoded

to=99999999&amount=10000

攻撃者の罠ページ

<!-- GETで勝手に送金 -->
<img src="https://bank.example.com/transfer?to=99999999&amount=10000" />

<!-- POSTで勝手に送金 -->
<form action="https://bank.example.com/transfer" method="POST">
  <input type="hidden" name="to" value="99999999">
  <input type="hidden" name="amount" value="10000">
</form>
<script>document.forms[0].submit();</script>

ユーザーがログイン中であれば、本人が送金操作をしていなくても処理が走ってしまいます。

対策:CSRFトークン

そこで必要なのがCSRFトークン

  • 各リクエストごとにユーザー専用のランダムなトークンを付与
  • サーバー側で一致するか検証
  • 一致しなければ拒否
    LaravelではBladeで次のように自動埋め込みされます。
<input type="hidden" name="_token" value="{{ csrf_tokent() }}">

サーバー側でセッションと照合し、合わなければ419 CSRF token mismatchを返します。

攻撃者が偽造した場合は?

攻撃者がフォームに{{ csrf_token() }}を書いても無意味です。

理由:

  • {{ csrf_token() }}はLaravelがログインユーザーごとに生成する一意な値
  • 攻撃者のHTMLでは単なる文字列"{{ csrf_tokne() }}"
  • サーバーで比較すると不一致→処理失敗

Vue + Laravel(Inertia)でのCSRF対策

Bladeを使わないVue構成でも、LaravelのVerifyCsrfTokenミドルウェアが働いているので、以下の設定をすればOKです。

  1. app.blade.phpにCSRFトークンを埋め込む
<meta name="csrf-token" content="{{ csrf_token() }}">
  1. axiosで自動的に送信するよう設定
    resources/js/bootstrap.jsなどで次を追加:
import axios from 'axios';

axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found');
}

これでVueからのフォーム送信やAPI呼び出し時にもCSRFトークンが自動で付与され、Laravel側で検証されます。

まとめ

  • CSRF攻撃は「ユーザーのログイン状態を悪用して不正リクエストを送る」手口
  • Laravel(Blade)では@csrfを使えば自動で対策できる
  • Vue + Inertia環境でもmetaタグ + axios設定で問題なくCSRF保護が効く
  • トークンが盗まれない限り攻撃は成立しない
    • 逆にXSSで盗まれると危険なので、XSS対策も重要
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?