Web 開発エンジニアであれば読んでおきたい本。600ページを超える大型本でかなり骨太である。サンプルコードは平易なPHPを例にしており読みやすい。

セキュリティと聞くと『バッファ・オーバーフローを起こさせてそこから任意のコードを実行し…』みたいな妄想が捗るが本書はそういった類のものではない。 この本を読むと、脆弱性を突いた攻撃がいかに簡単にできるか、あるいは少しの油断でいとも簡単に脆弱性のコードを書いてしまうのか、がよく理解できるだろう。

自分の覚書ではあるが、以下箇条書きで重要な用語とその説明をピックアップしておく。コード例や詳しい説明は本書を読んで欲しい。

同一オリジンポリシー

ブラウザのセキュリティ機能として、プログラムの利用が制限される sandbox という環境がある。JavaScript はその sandbox 環境化で動作するようになっている。 sandbox には以下の制限がある。

  • ローカルファイルへのアクセス禁止
  • プリンタなどの資源の利用禁止
  • ネットワークアクセスの制限 (同一オリジンポリシー)

XSS (クロスサイトスクリプティング) は 攻撃的な js を送り込んで同一オリジンポリシー下のもとで js を実行し、攻撃する手法である。

CORS (Cross Origin Resource Sharing)

先の同一オリジンポリシーにより別ドメインへのリクエストは厳しく制限されるが、一方で不便な場面に出くわすことも多い。そこで CORS という仕様が策定された。 これは header に Access-Control-Allow-Origin などを付与することによって Origin を超えたアクセスを許可できるようになる。

いくつか種類があるので以下を参照されたい (外部リンク、本書に記載無し)。

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

XSS とは外部からの入力などに応じて表示が変化する部分に関して攻撃をしかけること。

XSS の対策は属性値を " で囲んだり、特殊記号をエスケープすることで対策できる。しかしパターンが多数あり完全な対策は困難。

保険的対策として X-XSS-Protection ヘッダーを入れることで危険を軽減できる。これはブラウザがXSSを検知し無害な出力にエスケープしてくれる機能である。 Apache や Nginx の設定で付与しておくとよい。

クッキーに HttpOnly 属性を付与することによって、XSS 攻撃の典型的な手法であるセッションIDの盗み出しを防止することができる (限定的対応)。

JavaScript を動的生成している場合はこちらも同様にエスケープ処理をしなければいけないがルールが複雑。 できれば js の動的生成はしないようにする、がどうしてもしたい場合はカスタムデータ属性を利用するとよい。

SQL インジェクション

SQL インジェクションを阻止するにはプレースホルダーを使うようにするのが原則。

プレースホルダーには静的なものと動的なものがある。

静的プレースホルダーとは値のバインドをデータベースエンジン側で行うことを言う。 データベースエンジンによってSQL文がコンパイルされてから実行される。

動的プレースホルダーとはアプリケーションのライブラリなどでパラメータをバインドしてからデータベースに送ることを言う。

原理的に静的プレースホルダーであればSQLインジェクションの可能性がない。よって静的プレースホルダーを採用したほうがよい。

SQLインジェクションの保険的対策としては以下を実施する。

  • 詳細なエラーメッセージの抑止
  • 入力値の妥当性検証
  • データベースの権限設定

重要な処理と CSRF

Web アプリケーションには様々な機能があるが、その中でもクレジットの決済やパスワードの変更などの処理は特にセキュリティを意識すべき機能である。そのような処理を「重要な処理」と呼ぶことにする。 重要な処理を悪用したものとして CSRF (クロスサイトリクエストフォージェリ) が挙げられる。

CSRF の攻撃例は以下のようなものがある。

  • 利用者のアカウントによる物品の購入
  • 意図しない退会処理
  • 利用者のメールアドレスやパスワードの変更

CSRF 脆弱性の対策は、こうした重要な処理の前には利用者の意図したリクエストであることを確認することである。

CSRF の攻撃方法のシナリオ例を示す。

  • 利用者がサービスのログインしている
  • 攻撃者が罠サイトを設置する
  • 利用者が罠サイトを閲覧する
  • 罠の JavaScript により、被害者のブラウザ上で攻撃対象サイトに対し、パスワード変更のPOSTメソッドを送信する
  • パスワードが変更される

hidden パラメータなどで確認画面を挟んでいても先程の例のような攻撃は可能である。

セッション変数でパラメータを受け渡している場合においても、以下のような方法で攻撃が可能である。

  • 確認画面に対してメールアドレスをPOSTしてセッション変数にメールアドレスをセット
  • タイミングを見計らって実行画面を呼び出す

実装は iframe を2段にすることで可能になる。

CSRF 脆弱性が生まれる背景には Web の性質が関係している。

それは

  1. form要素のaction属性にはどのドメインのURLでも指定できる
  2. クッキーに保管されたセッションIDは、対象サイトに自動的に送信される

というものである。

1 は罠サイトからでも攻撃対象サイトにリクエストが送信できることを意味し、 2 は罠経由のリクエストでもセッションIDのクッキー値が送信されるので認証された状態で攻撃リクエストが送信されるということを意味する。

CSRF の対策は、対策の必要なページを区別し、正規利用者の意図したリクエストを確認できるようにすることである。 対策の必要なページというのは、ECサイトを例にするとカート商品の購入処理であったり、会員情報のパスワード変更やクレジットカード登録などである。

正規利用者の意図したリクエストの確認方法は、秘密情報 (トークン) の埋め込み、パスワード再入力、リファラのチェックがある。なおトークンは第三者に推測されにくい乱数を用いて生成する。

CSRF を防ぐ対策ではないが、重要な処理の実行後にメールアドレスに処理内容を通知することで、CSRF 攻撃が起きたときの被害を縮小できる。 ただしメールは平文なので重要な情報は含めずに、重要な処理が実行されたことだけをメール送信する。 詳細内容はサイトにログインして購入履歴や送信履歴をみるようにしてもらう。

クリックジャッキング

特定のボタンなどを利用者の気づかない方法でクリックさせることができれば、重要な処理を実行させることができる。 クリックジャッキングは iframe と CSS を巧妙に利用したものである。

例としては、掲示板のような投稿サイトで、投稿フォームに攻撃用の文言を iframe で設置し不透明度0%にして見えないようにする方法などがある。

クリックジャッキングはアプリケーション単体では対策が困難なためブラウザ側の支援が必要となる。 このため frame および iframe での参照を制限する X-Frame-Options という仕様がある。

X-Frame-Options はレスポンスヘッダとして定義されており、DENYSAMEORIGIN のいずれかの値を取る。 frame や iframe を使わないサイトでは DENY を指定、frame などを使っているホストが単一の場合は SAMEORIGIN を指定する。

手軽な実装としては、Apache や Nginx の設定で X-Frame-Options ヘッダを出力する方法がある。

セッション管理の不備

Web アプリケーションでは認証結果などの状態を記憶する手段として、セッション管理機構が用いられている。 現在主流のセッション管理機構はクッキーなどにセッションIDという識別子を記憶させ、このセッションIDをキーとしてサーバー側で情報を記憶する方法が取られている。

セッションハイジャックの手法は多岐に渡る。

対策としては下記の通り。

  • セッション管理機構は自作せずにライブラリなどを使う
  • クッキーにセッションIDを保存する
  • 認証成功時にセッションIDを変更する
  • 認証前にはセッション変数に秘密情報を保存しない

クッキーの属性について

1
2
3
4
5
Domain: 指定しないのがデフォルトかつ最も安全
Path
Expires
Secure: この属性をつけると https のみサーバーに送信される、できればつける
HttpOnly: これをつけると js からアクセスできないようにできる、つけた方がよい

リダイレクト処理にまつわる脆弱性

Web アプリケーションの中にはパラメータに指定したURLにリダイレクトできる機能を備えているものがある。 その中で任意のドメインにリダイレクトできる脆弱性をオープンリダイレクト脆弱性と呼ぶ。フィッシング詐欺などに利用される。

脆弱性が生まれる原因

リダイレクト先のURLが外部から指定でき、かつリダイレクト先のドメインチェックがない場合に起こる。 対策としてはリダイレクト先のURLを固定化する、リダイレクト先のURLを直接指定せず番号指定にする、リダイレクト先のドメイン名をチェックするといった方法がある。

HTTP ヘッダインジェクション

リダイレクトやクッキー生成など、外部から指定したパラメータに基づいて HTTP レスポンスヘッダを出力している箇所で発生する。

レスポンスヘッダが偽装されることで任意のクッキーの生成、任意のURLへのリダイレクト、表示内容の改変、JavaScript 実行による XSS と同等の被害が起こる可能性がある。 対策として、外部からのパラメータを HTTP レスポンスヘッダとして出力しないようにする。

脆弱性診断入門

本書後半の7章では以下のツールを用いて脆弱性のあるサンプルアプリに対して診断を行う方法が記されている。

  • OWASP ZAP
  • Nmap
  • OpenVAS
  • RIPS

全体を通しての書評

ここまで書いたことはまだ一部であってその他にも様々な脆弱性とその対策について記載されている。 例えば Web API や DOM Based XSS といった JavaScript のセキュリティについても紹介されている。

Web セキュリティに関してはこの本は必読だと思うので読んでおくべし。

P.S.

本の著者である徳丸さんの書かれたスライド。 こちらは Rails を題材にして種々の脆弱性を紹介している。