SPA開発をするにあたって、モノリスなアプリケーションと意識するところが違うためにCSRFとXSSへの理解を深める必要があるなーと感じたので、これら2つについて様々なサイトを参考にしながら自分なりのメモとしてまとめてみることにした。
「XSS」
ユーザーがサイトにアクセスした際に不正なスクリプトが実行されてしまう攻撃手法や脆弱性のこと。
・基本的な攻撃手法
スクリプトを埋め込むことで、フォームなどに入力させたユーザー情報を奪い取る。
外部URLからユーザーに不正アクセスをさせて、cookieなどを送信させて奪い取ったり。
・代表的な対策
表示する文字を表示前にエスケープ処理するなど。
XSSの3つの種類
・反射型XSS
これは、外部から受け取ったパラメータをWebページに表示する際に起こる脆弱性だ。
嬉しいことに、ChromeやSafariなどのブラウザでは反射型XSSへの対策が進んでいるらしい。ただ、100%ではないので注意しないといけないようだ。
以下のサイトでは実際にセッションハイジャックの手順が紹介されており、試してみようと思う。
・格納型/蓄積型/持続型XSS
これは、DBに悪意のあるスクリプトが保存されてしまうことでそのDBにあるスクリプトを表示する際に悪意のあるスクリプトが毎回実行されてしまうタイプのXSSのことを指します。
ユーザーがアクセスするたびに実行されてしまうため、格納型/持続型と呼ばれます。
・DOM-based XSS
これは、ブラウザ側JavaScriptによって起こされる脆弱性のこと。
DOM-based XSSが厄介な理由1
近年のブラウザが用意している「レスポンス内の文字列でスクリプトが発生した場合XSSとみなす」という仕組みが、サーバーにリクエストがいかないDOM-based XSSの場合機能しないことが多い。
理由2
XSSによる被害が大きくなったとしても、ログが残らないがゆえに問題の把握がしにくいということ。
DOM-based XSS を防ぐために知っておきたいこと。
ソース→シンクの流れの中でスクリプトが実行されてしまうので、ソースかシンクとなるメソッドを知っておくと良さそう。
基本的にはDOM操作を適切に行うことを意識して行くべき。以下のページには具体例がある。
https://gihyo.jp/dev/serial/01/javascript-security/0006?page=2
「CSRF」
ユーザーが予期しないURLやオリジンからリクエストを送らされることで、ユーザーのデータが操作されてしまう攻撃手法のこと。
・代表的な攻撃手法
外部URLを介してForm入力を行い、POSTなどのリクエストを送るだけ。
・対策
リクエストが正しいルートからのものなのか検証をする。
具体的には、サーバー側がFormページ返却時にトークンを付与。次回リクエスト時にトークンを検証してユーザーの一致を確認するなど。
モノリスなLaravelで対策を行う場合
LaravelでのCSRF対策は、バックエンドから配布されたHTMLformとsessionにトークンを仕込み、formなどからリクエストがあった際にform内のトークンとsession内のトークンが一致するか確認することで行っている。
SPAなLaravalで対策を行う場合
/sanctum/csrf-cookie
エンドポイントにリクエストを送信して、アプリケーションのCSRF保護を初期化(有効にして使える状態)する必要がある。
方法は2種類あり、トークンを生成する方法とCookieベースの認証を採用する方法である。
「CSRFとCORSの関係」
SPAにおいてCORSは必要不可欠なものだが、CSRF対策はこのCORSを用いた2段階の壁を作ることで実施することができる。
CORSはサーバー側でアクセスを許可するオリジンを設定することで異なるオリジン間の通信を制限するというもの。
Access-Control-Allow-Origin
というレスポンスヘッダを利用する。
これはあくまでもアクセス制限をしているだけでサーバーに対するアクセス自体は成功してしまう問題がある。
そこで、プリフライトリクエストを使用する。
これによってそもそもサーバー側にリクエストを届かなくできる。
(参照記事)
SPA の CSRF 対策や CORS について検証する - 30歳からのプログラミング
・Preflight request (プリフライトリクエスト)
プリフライトリクエストは CORS のリクエストの一つであり、サーバーが CORS プロトコルを理解していて準備がされていることを、特定のメソッドとヘッダーを使用してチェックします。
Preflight request (プリフライトリクエスト) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN
これは、OPTIONメソッドを使ったリクエストである。
これは OPTIONS リクエストであり、 Access-Control-Request-Method,Access-Control-Request-Headers, Origin の3つの HTTP リクエストヘッダー使用します。
OPTIONSメソッドによるリクエストが発生するというのが重要で、ここで許可されていないリクエストは排除されるため、上記のようにサーバー側に不正なリクエストが届くことがない。
これがプリフライトリクエストと呼ばれるものだ。
では、どうやってPreflight request (プリフライトリクエスト)を発生させるかだが、その方法はいろいろある。
・リクエストに独自ヘッダをつければ、必ず発生する。
axiosなどでは、application/jsonなどのヘッダがデフォルトでついていたような気がする。