理系学生日記

おまえはいつまで学生気分なのか

「安全なウェブサイトの作り方 改訂第7版」を読んだ

セキュリティのガイドを書けという話があり、日本で最も基本的なところであろうIPAの「安全なウェブサイトの作り方」の1章を再確認します。

対策の種類

脆弱性対策には2種類があり、根本的対策と保険的対策です。

根本的対策はそもそもとして「脆弱性を作り込まない実装」を実現するための手段であり、 保険的対策は「攻撃による影響を軽減する対策」です。

ウェブアプリケーションのセキュリティ実装

以下の11種類とそれぞれの対策が挙げられています。少なくとも根本的対策の方はおおよそ王道が記載されているのではないでしょうか。

実際の内容としてはどのようなケースでどのような対策を取るべきかという分岐や、詳細な対策内容が記述されているので、 ご興味のある方はぜひ実際に読んでみることをお勧めします。

第6版からはクリックジャッキングとバッファオーバーフローが追加されてようですが、いずれも一般的に知られている脆弱性と言って良いでしょう。注意すべきは、この内容はIPAに届出が多かった脆弱性や攻撃による影響度が大きい脆弱性を取り上げたものであり、これが全てではないということです。また、こちらの作成年月日は2015/03ということなので、より最新の情報が必要ならOWASP Top Tenあたりを見ていただくのが良いでしょう。

IPAの届出状況は脆弱性関連情報の届出状況:IPA 独立行政法人 情報処理推進機構から参照可能です。

参考までに、2020年度第四四半期のWEBアプリケーションに関する脆弱性の種類・影響別届出件数をソフトウェア等の脆弱性関連情報に関する届出状況[2020年第4四半期(10月~12月)]:IPA 独立行政法人 情報処理推進機構から引用します。

  1. SQLインジェクション
    1. 根本的対策
      1. SQL文の組み立ては全てプレースホルダで実装する
      2. SQL文の組み立てを文字列連結により行う場合は、エスケープ処理等を行うデータベースエンジンのAPIを用いて、SQL文のリテラルを正しく構成する
      3. ウェブアプリケーションへ渡されるパラメータにSQL文を直接指定しない
    2. 保険的対策
      1. エラーメッセージをそのままブラウザに表示しない
      2. データベースアカウントに適切な権限を与える
  2. OSコマンド・インジェクション
    1. 根本的対策
      1. シェルを起動できる言語機能の利用を避ける
      2. シェルを起動できる言語機能を利用する場合は、その引数を構成する全ての変数に対してチェックを行い、あらかじめ許可した処理のみを実行する
  3. パス名パラメータの未チェック/ディレクトリトラバーサル
    1. 根本的対策
      1. 外部からのパラメータでウェブサーバー内のファイル名を直接指定する実装を避ける
      2. ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする
    2. 保険的対策
      1. ウェブサーバー内のファイルへのアクセス権限の設定を正しく管理する
      2. ファイル名のチェックを行う
  4. セッション管理の不備
    1. 根本的対策
      1. セッションIDを推測が困難なものにする
      2. セッションIDをURLパラメータに格納しない
      3. HTTPS通信で利用するCookieにはsecure属性を加える
      4. ログイン成功後に、新しくセッションを開始する
      5. ログイン成功後に、既存のセッションIDとは別に秘密情報を発行し、ページの遷移ごとにその値を確認する
    2. 保険的対策
      1. セッションIDを固定値にしない
      2. セッションIDをCookieにセットする場合、有効期限の設定に注意する
  5. クロスサイト・スクリプティング
    1. 根本的対策
      1. ウェブページに出力する全ての要素に対して、エスケープ処理を施す
      2. URLを出力するときは、「http://」や「https://」で始まるURLのみを許可する
      3. <script>...</script> 要素の内容を動的に生成しない
      4. スタイルシートを任意のサイトから取り込めるようにしない
      5. 入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する
      6. HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)を指定する
    2. 保険的対策
      1. 入力値の内容チェックを行う
      2. 入力されたHTMLテキストから、スクリプトに該当する文字列を排除する
      3. Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、TRACEメソッドを無効化する
      4. クロスサイト・スクリプティングの潜在的な脆弱性対策として有効なブラウザの機能を有効にするレスポンスヘッダを返す
  6. CSRF(クロスサイト・リクエスト・フォージェリ)
    1. 根本的対策
      1. 処理を実行するページをPOSTメソッドでアクセスするようにし、その「hiddenパラメータ」に秘密情報が挿入されるよう、前のページを自動生成して、実行ページではその値が正しい場合のみ処理を実行する
      2. 処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する
      3. Refererが正しいリンク元かを確認し、正しい場合のみ処理を実行する
    2. 保険的対策
      1. 重要な操作を行った際に、その旨を登録済みのメールアドレスに自動送信する
  7. HTTPヘッダ・インジェクション
    1. 根本的対策
      1. ヘッダの出力を直接行わず、ウェブアプリケーションの実行環境や言語に用意されているヘッダ出力用APIを使用する
      2. 改行コードを適切に処理するヘッダ出力用APIを利用できない場合は、改行を許可しないよう、開発者自身で適切な処理を実装する
    2. 保険的対策
      1. 外部からの入力の全てについて、改行コードを削除する
  8. メールヘッダ・インジェクション
    1. 根本的対策
      1. メールヘッダを固定値にして、外部からの入力はすべてメール本文に出力する
      2. メールヘッダを固定値にできない場合、ウェブアプリケーションの実行環境や言語に用意されているメール送信用PIを使用する
      3. HTMLで宛先を指定しない
    2. 保険的対策
      1. 外部からの入力の全てについて、改行コードを削除する
  9. クリックジャッキング
    1. 根本的対策
      1. HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限する
      2. 処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する
    2. 保険的対策
      1. 重要な処理は、一連の操作をマウスのみで実行できないようにする
  10. バッファオーバーフロー
    1. 根本的対策
      1. 直接メモリにアクセスできない言語で記述する
      2. 直接メモリにアクセスできる言語で記述する部分を最小限にする
      3. 脆弱性が修正されたバージョンのライブラリを使用する
  11. アクセス制御や認可制御の欠落
    1. 根本的対策
      1. アクセス制御機能による防御措置が必要とされるウェブサイトには、パスワード等の秘密情報の入力を必要とする認証機能を設ける
      2. 認証機能に加えて認可制御の処理を実装し、ログイン中の利用者が他人になりすましてアクセスできないようにする