はじめに
ウェブアプリケーションのアーキテクチャとしてSPA(シングルページアプリケーション)とMPA(マルチページアプリケーション)は広く使用されています。しかし、それぞれのアーキテクチャには異なるセキュリティ上の懸念事項があります。本記事では、SPAとMPAにおける主要なセキュリティ上の脅威とそれに対する対策についてざっくり解説します。
XSS(クロスサイトスクリプティング)への対策
XSSは、ウェブアプリケーションへの悪意のあるスクリプトの注入による攻撃です。
ユーザーの情報の盗聴や操作、セッションの乗っ取りなどの被害に繋がります。
SPAでの対策
- エスケープ処理
ReactやAngularのような現代のフロントエンドフレームワークでは、デフォルトでXSS対策が施されており、ブラウザにレンダリングされる前に値を自動的にエスケープすることで、悪意のあるスクリプトの実行を防ぎます。
- CSPの使用
しかし、信頼できないソースからデータを取得する場合や、ユーザからの入力をそのまま反映する場合など、自動的なエスケープが機能しない状況もあります。その場合は、CSP(Content Security Policy)を適用することで、特定のソースからしかスクリプトを読み込めないように制限を設けることが有効です。
webサーバのレスポンスヘッダに"Content-Security-Policy"を設定し、特定のドメインからのスクリプトやリソースの読み込みを許可します。
// 例
Content-Security-Policy: default-src 'self'; img-src \*; media-src media1.com media2.com; script-src userscripts.example.com
default-src 'self'
すべてのコンテンツを、サイト自身のドメイン(サブドメイン除く)から取得させることを表す。
img-src *
任意のドメインからの画像の読み込みを許可する。
media-src media1.com media2.com;
音声や動画などのメディアは media1.com media2.com のみ許可される。
script-src userscripts.example.com
userscripts.example.com のスクリプトのみ実行可能。
MPAでの対策
- エスケープ処理
MPAにおけるXSS対策として最も一般的なのは、サーバーサイドでの出力エスケープです。これは、HTMLに含まれる特殊文字(例:<、>、&など)を安全な表現(例:<、>、&)に置き換える処理を指します。
例えばPHPの場合、htmlspecialchars関数を使用してエスケープを行うことができます。
// 例
echo htmlspecialchars('<script>alert("XSS")</script>', ENT_QUOTES, 'UTF-8');
また、SPAと同様に、CSPを適用することも有効です。
CSRF(クロスサイトリクエストフォージェリ)への対策
CSRFは、攻撃者が被害者の代わりに不正なリクエストを送信する攻撃です。
攻撃者は被害者の認証情報を利用し、意図しない操作を実行させることができてしまいます。
SPAでの対策
SPAのCSRF対策においては、HTTP Only Cookieとともにトークンベースの認証方法を使用するのが一般的です。JWT (Json Web Token) のような状態を保持しない認証トークンを用い、これをlocalStorageやsessionStorageに保存します。
※「JWTの保存先はlocalStorageとsessionStorageのどちらが良いか」という話もありますが、自分はどちらでもいいのかなと思ってます。
しかし、トークンはJavaScriptからアクセス可能であるため、悪意のあるスクリプトによって盗まれてしまう可能性はあります。
MPAでの対策
- CSRFトークンの使用
対策としてよく用いられる方法が「トークンを用いた対策」です。
各フォーム送信に対して一意なCSRFトークンを発行し、クライアントからのリクエストに対してそのトークンが含まれていることを確認します。
具体的には、以下の流れに沿っています。
ユーザーがアクセスした時、サーバーは一意のCSRFトークンを生成し、フォームとともにクライアントへ送信。
↓
ユーザーがフォームを送信する際に、このトークンをリクエストとともにサーバーへ送信。
↓
サーバー側では送信されてきたトークンを元にしたものと照合。
(一致しない場合はリクエストを拒否。)
さいごに
Webのセキュリティの基本であるXSS及びCSRFへの対策について、SPAとMPAの両方の視点からそれぞれ簡単な対策をまとめました。
いやもっと他にもあるやろ......、と感じた方はコメント頂けますと幸いです。