はじめに
本記事では、認証・認可まわりで特に注意すべき脆弱性と対策を整理してみます。
CSRFとXSS
まず、CSRF(クロスサイトリクエストフォージェリ)。
ユーザーがログイン中に攻撃者が用意したページを踏んでしまうと、本人のセッションがそのまま使われてしまい、送金や投稿などを勝手に実行される可能性がある。
上記を防ぐにはCSRFトークンを使って「本当に正規のフォームから送信されたのか」を検証したり、SameSite属性付きCookieを利用したりする必要がある。
ただ、CSRFトークンは万能ではない。
システムにXSS(クロスサイトスクリプティング)が存在すれば、攻撃者は正規ページにスクリプトを仕込んでトークン自体を盗み出すことができる。
そのため、CSRF対策は必ずXSS対策とセットで考える必要がある。
XSSを防ぐには、出力時のエスケープ処理やContent Security Policy (CSP)の導入、そしてセッションIDを格納するCookieにはHttpOnly属性を付けてJavaScriptから参照できないようにすることが基本。
※Content Security Policy (CSP)とは
ブラウザに「このページでどんなリソースを実行していいか」を制御させる仕組み。
サーバーがレスポンスヘッダーでポリシーを指示すると、ブラウザがそれに従って不要なスクリプトやリソースをブロックする。
(例)自分自身のドメインからのリソースだけ許可し、それ以外は禁止
Content-Security-Policy: default-src 'self'
セッション固定攻撃
攻撃者があらかじめ用意したセッションIDを被害者に使わせ、ログイン後も同じIDで不正利用する手口。
防ぐにはログイン成功時に必ず新しいセッションIDを発行すること。
セッションハイジャック
Cookieに保存されたセッションIDを盗まれてしまう攻撃。
HTTPSを使わずに通信すると盗聴されやすく、XSSがあればJavaScript経由でCookieを奪われる危険もある。
Secure属性やHttpOnly属性を付けたCookieを利用し、一定時間でセッションをタイムアウトさせることが有効な防御策。
パスワード攻撃
総当たりによるブルートフォースや、漏洩したID・パスワードの組み合わせを使ったクレデンシャルスタッフィングは非常に多い攻撃手法。
対策としては、ログイン試行回数の制限、アカウントロック、多要素認証、そしてパスワード強度のチェックを組み合わせる必要がある。
また、ログインの認証時間を伸ばすのも1つの手。
リプレイ攻撃
一度有効だったリクエストを再送することで処理を繰り返させる攻撃。
決済や退会処理など、同じリクエストが何度も通ってしまうと大きな被害につながる。
対策としては、ワンタイムトークンやリクエストIDを導入して重複を防ぎ、処理の冪等性(べきとうせい)を確保することが挙げられる。
※冪等性の確保とは
同じリクエストを何度受けても最終的なシステムの状態が変わらないようにすること。
まとめ
認証や認可は「ログインさせる」「権限を振り分ける」だけでは安全とは言えません。
CSRFやXSSのようにユーザーの意図しない操作を行わせる攻撃、セッションを盗んだり固定したりする攻撃、パスワードや権限チェックを突破する攻撃など、さまざまな脅威があります。
そのため、どれか一つだけを対策しても抜け道が生まれるため、多層的な防御を組み合わせることが不可欠だと思いました。