Webアプリケーション開発の標準 =================================== 概要 --------------------------- Webアプリケーションには, 正しく実装しなければ個人情報の流出などの重大な事件を起こすリスクがある. サービスの開発者は, 注意深くWebアプリケーションを実装しなければならない. 「安全なウェブサイトの作り方」への準拠 -------------------------------------------------------------------- サービスの開発者は, `情報処理推進機構:情報セキュリティ:脆弱性対策:安全なウェブサイトの作り方 `_ に準拠してサービスを実装しなければならない. ただし, 以下で補足する事項や他の標準によって規定されている事項は除く. 「安全なウェブサイトの作り方」への補足事項 -------------------------------------------------------------------- 以下では, `安全なウェブサイトの作り方 `_ に対する補足を記述する. 1.1 SQLインジェクション ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * サービスの開発者は, 言語やフレームワークで用意されているバインド機構が安全であるか確認しなければならない. 1.4 セッション管理の不備 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * サービスの開発者は, 言語やフレームワークで用意されているセッション機構が安全であるか確認しなければならない. * セッションIDに十分なエントロピーが含まれているか * セッション情報が格納されるのはどこか. 格納先でどのようなリスクがあるか. * セッション情報がDBに格納されるのであれば, 個人情報などを格納するのを避けなければならない. * 格納先のリスクによってはログアウト時にセッション情報を消去するようにする必要がある. * セッション情報の消去は保険的な対策として, 常に行なってもよい. * サービスの開発者は, 個人情報を閲覧/編集する画面などにsecure属性のないセッションIDだけでアクセスできないように実装しなければならない. * 可能であれば セッションクッキーに対して httponly 属性を付与する. 1.5 クロスサイト・スクリプティング(XSS) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ XSS対策まとめ ################################################ サービスの開発者は, クロスサイト・スクリプティング防止のために以下を行なわなければならない. * HTTPからの入力のエンコーディングをチェック/変換しなければならない * HTML出力時にエンコーディングを意識してHTMLエスケープしなければならない * a要素のhref属性やimg/iframe要素のsrc属性などにURLを出力する際は, http, httpsスキーマのみ許可しなければならない. * HTTPヘッダで正しいContent-Type, Charsetを指定しなければならない. * JavaScript, CSSを動的に生成してはならない. * JavaScript, CSSのURLを動的に変更する場合は, 特定のURLのみを許可するようにしなければならない. 参考: `ブラウザ上でMarkdownを安全に展開する - 葉っぱ日記 `_ JavaScript利用時の注意 ################################################ TODO: JavaScriptの手順に分離 サービスの開発者は, 「3) 要素の内容を動的に生成しないように」しなければならない. script要素の内部で動的な情報を取り扱いたい場合には, 画面に表れないHTMLの要素を利用する. * 標準的には, input要素(type="hidden")のvalue属性値に動的な情報を定義して(HTMLエスケープは行なうこと)スクリプトからDOM経由で参照する. * `JavaScript の Unicode エスケープシーケンスに変換する - Sarabande.jp `_ のようなエスケープ方式を利用して, 動的な文字列をエスケープして JavaScript の文字列リテラルに埋め込む方法を利用してもよい. * サービスの開発者は, JavaScriptのdocument.write(), document.writeln()関数や, innerHTML, outerHTMLプロパティ, JQueryの.html()関数などを用いて動的な情報を出力することを避ける必要がある. これらの方法は指定した値のHTMLエスケープを行わない. これらの方法を利用しなければならない場合は, 適切なHTMLエスケープを行なわなければならない. もしくは, 適切にHTMLエスケープを行なうテンプレートエンジンを利用しなければならない. 参考: `escapeHTML の実装 3 パターン (ベンチマーク付き) - (new Hatena).blog() `_ 1.6 クロスサイト・リクエスト・フォージェリ(CSRF) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * 参考資料: `CSRF対策用トークンの値にセッションIDそのものを使ってもいい時代なんて、そもそも無かった `_ , `開発者のための正しいCSRF対策 `_ * サービスの開発者は, CSRF対策用の秘密情報に以下の情報を用いる必要がある. * 十分なエントロピーを持つ乱数源から得られるトークン * 言語で安全な乱数をサポートしている場合は利用する * そのようなサポートがない場合は, OSの機構を利用する. * GNU/Linux の場合は /dev/urandom が利用できる. random(4) 参照. * ワンタイムではないトークンの場合は, あるページにXSSがあった場合などにトークンが漏洩しCSRFが可能になるリスクがある. ワンタイムトークンの場合はこのリスクがないが, 毎回トークンを生成するコストがかかる. リスクとコストを考えてシステムに適当なものを採用すること. * セッションIDが漏洩した場合に, そのセッションIDを攻撃者が利用すると(UserAgent や IPアドレスなどの)環境の違いを検出しセッションを破棄する仕組みをアプリケーションに組込む場合がある. このとき, トークンとして(他の秘密情報を含まない)セッションIDのハッシュ値(ハッシュを繰り返し利用する場合の含む)を利用していると, 攻撃者にハッシュ方法を特定されセッションハイジャックは困難だがCSRFは可能という状態になることが考えられる. 攻撃者に推測できない秘密情報を鍵とする鍵付きハッシュ(HMACなど)を利用すればこの状態は防げるが鍵の管理が必要となる. * このため, セッションIDに関係のないトークンの利用がトークン生成のコストはかかるが適当だと判断する. ただし, フレームワークなどで用意されている方法があればそれを利用してもよい. フレームワークが提供する方式は適当かどうかとフレームワークが利用する秘密情報に十分なエントロピーが含まれているか確認すること. * サービスの開発者は, ログイン/ログアウト機能でもCSRF対策を行なったほうがよい. 少なくとも重要な情報を扱うアプリケーションではログイン機能でのCSRF対策を行なわなければならない. 理由は, `ログイン機能へのCSRFによるセッション固定 - 知らないけどきっとそう。 `_ を参照. CSRF トークンの送信された値と期待値との比較には, 応答時間によりトークンの値を推測されるのを防ぐため実行時間が文字列長にのみ依存する方式を利用したほうがよい. 2.3 ネットワーク盗聴への対策 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * サービスの開発者は, 重要の情報を取り扱うウェブページへの暗号化していない(httpでの)アクセスを禁止しなければならない. 2.4 パスワードの不備 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * 「4) パスワード入力のフォームでは、入力文字列を伏せ字で表示する」とあるが, ユーザビリティを考慮して入力中のパスワードを表示してもよい. Webアプリケーションセキュリティチェックシート -------------------------------------------------------------------- (ECナビ固有の情報のため削除) その他の遵守事項 -------------------------------------------------------------------- 利用者の退会の対応 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ サービスは, 利用者の退会が可能でなければならない. サービスの開発者は, 退会機能を用意する必要がある. 退会機能を用意することが難しい場合には, メールなどによるお問合せでの退会を受けつける必要がある. サービスは, 運用上退会後も一定期間情報の保持が必要な場合を除き利用者の退会直後に機密情報を削除しなければならない. 退会後に一定期間の情報の保持が必要な場合は, 期間終了後に機密情報を削除しなければならない. 機密情報の削除については, :ref:`web-standard-cryptograpy` の :ref:`secure-remove` も参照すること 利用者へのメールでの連絡 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 機密情報の記述の禁止 ######################################### サービスは, メールに利用者の個人情報(住所, 電話番号など)を記述してはならない. ただし, BtoBサービスなどで利用者の個人情報が公開情報であることが期待される場合は除く. メールのサンプルの表示 ############################################################## サービスは, 利用者に定期的に送られるメールについて具体的な内容とおおまかな送信日時をサイトに明示したほうがよい. ログインなどの履歴の保持と利用者への表示 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 機密情報を扱うサービスは, ログイン履歴を記録し利用者に対し閲覧可能にすることを推奨する. ログイン履歴が閲覧可能なことで, 侵入の抑止力となったり事故の早期発見につながるといった効果が期待できる. 少なくとも, ログイン日時とログイン時のIPアドレスを記録すること. 他に UserAgent などの情報を記録してもよい. ログインだけなく, 重要な操作についての履歴を残し利用者に対し閲覧可能にしてもよい. 2要素認証 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 機密情報を扱うサービスは, 2要素認証の利用を可能にすることを推奨する. HTTPS ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO: 文章が適当 HTTPS で保護されたページでの画像・CSS・JavaScript ################################################## サービスの開発者は, HTTPS で保護されたページでは画像・CSS・JavaScriptなどもhttpではなく https でアクセスするようにしなければならない. ただし, そのページがhttp/https どちらでもアクセスできかつ何ら機密情報などを含まないものであれば, http でのアクセスを許してもよい. httpページにhttpsページの(i)frameの禁止 ######################################## httpのページにhttpsのページをframeやiframeで出力してはならない. HTTP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * 参考 * `1分でわかる「X-ナントカ」HTTPレスポンスヘッダ - 葉っぱ日記 `_ * `今夜つける HTTPレスポンスヘッダー (セキュリティ編) - うさぎ文学日記 `_ X-Content-Type-Options: nosniff の付与 ################################################# HTTPレスポンスヘッダで * X-Content-Type-Options: nosniff を出力すると, Internet Explorer 8以降でコンテンツの内容からファイルタイプを決定しないように強制できる. すべての動的コンテンツのレスポンスヘッダで出力することを推奨する. * `X-Content-Type-Options: nosniff つかわないやつは死ねばいいのに! - 葉っぱ日記 `_ * `X-Content-Type-Options: nosniffのつけ方 | へぼい日記 `_ X-Frame-Options の付与 ################################################ すべてのページで X-Frame-Options を適当に設定することを推奨する. 今後も含めフレームなどでの埋め込みを許さないのであれば DENY を 同じオリジンからの埋め込みを許すのであれば SAMEORIGIN を設定する. * `The X-Frame-Options response header - HTTP | MDN `_ ただし, ブログパーツなど他のサイトに埋め込まれるページは除く. そのようなページの場合は, ALLOW-FROM のサポートが主要なブラウザで行なわれたらALLOW-FROM の利用も検討する. その他のヘッダ ################################################ 新たにサイトを構築する場合は `CSP (Content Security Policy) `_ の利用を検討する. HTTP と HTTPS を併用している場合は, `HTTP Strict Transport Security `_ の利用を検討する. IPアドレス制限 -------------------------------- 要件によりIPアドレス制限をする場合は, 攻撃者によるIPアドレスの偽装が困難な方式でIPアドレスを取得しなければならない. * `PHP フレームワークでのクライアント IP アドレス取得メソッドの実装について - A Day in Serenity @ Kenji `_