開発:セキュリティ
作成中です - Mitsuhiro Yoshida 2010年1月9日 (土) 15:53 (UTC)
このページでは、不道徳な人たちがMoodleサイトを攻撃できないよう、セキュアなMoodleコードを書く方法を記述します。
また、ページでは、一般的なタイプの脆弱性について整理しています。それぞれのタイプに関して、以下のことを説明します:
- 危険性とは
- トラブルを避けるため、Moodleはどのように設計されているか
- Moodle開発者として、あなたのコードをセキュアなものにするには何をすべきか
- あなたのMoodleをさらに安全にするため、管理者として何をすべきか
それぞれの脆弱性に関する説明は、下記一覧にリンクされるページにあります。
また、このページでは、ガイドラインのキーとなる内容すべてに関して、要約しています。
ウェブアプリケーションのセキュリティ
ウェブアプリケーションをセキュアにするための必要条件
いくつかの法人では、ウェブアプリケーションに関して、最大レベルのセキュリティを要求しています。多くの場合、あなたは類似の一般的な推奨内容を読むことになります:
- 管理バックエンドを分離する。
- ウェブアプリケーションに機密情報を保存しない。
- SSLを使用して、コミュニケーションを暗号化すべき。
- ユーザすべての行動をログに記録する。
- サーバアプリケーションは、完全に分離されるべき。
- ユーザからサーバにファイルをアップロードさせない。
- ユーザからサーバにリッチテキストを入力させない (プレインテキストのみに制限する)。
- 分離されたチャネル経由で、ユーザIDおよび操作を認証する。
- すべてのソフトウェアを常に最新にする。
- サードパーティのブラウザ拡張モジュールを推奨しない。
- 1つのウェブページのみ使用して、異なるサイトを複数のウィンドウで開かない。セキュアアプリケーションを使用する前および後に、ブラウザを閉じる/開く。
ウェブベースのバンキングシステムは、これらの「セキュア」なウェブアプリケーションの良い例です。ここではセキュリティが最優先されます - セキュリティ上の問題は、顧客、銀行または保険会社にコストを発生させ、銀行の世間一般に対するイメージも失墜させます。限定要因は、アプリケーション開発、メンテナンス、ユーザビリティであると考えられますが、代替チャネルでのコミュニケーションコストも含まれます。
安定したセキュリティ
今日、あなたは、数多くのウェブアプリケーションがセキュリティデザインのルールに反していることを知ることができます。例えば、ウェブベースのメールシステムでは、添付ファイルとしてリッチテキストを受け入れたり、極めて機密な情報をメールメッセージが含んだりしています。実際のところ、Web 2.0の考え方はセキュリティデザインのルールに直接反して、誰でもコンテンツを送信することができます - アプリケーション開発者/管理者のみ信頼できるコンテンツを追加すべきです。
ウェブアプリケーションを設計する場合、私たちのユーザが何をサポートされるべきか調査して、機能およびセキュリティ間の適切なバランスを探ります。
Moodleセキュリティデザイン
ウェブアプリケーションのセキュリティは、使用目的およびそれぞれのタイプのユーザが利用できる機能に依存します。
ユーザタイプ
管理者
管理者には、以下の権限があります:
- すべての設定を変更する
- コースを作成する
- すべてのコースにアクセスする
- 言語パックを変更する
- すべてのユーザを変更する
間接的に、管理者はシェルおよびPHPコードの実行を許可されます。Moodle管理者は、config.php内のハードコードされた設定により、制限を受ける場合もあります。低水準のサーバでは、管理者はPHPコードを読んで修正することができるため、権限を制限することはできません。
すべての管理者は、完全に信頼された存在です。
教師
通常、教師はコースコンテンツを作成して、学生をコースに登録した後、指導します。また、教師には、以下の権限が必要です:
- ファイルのアップロードおよびHTMLテキストの送信
- 活動の作成および管理
- 学生の評点および他の個人情報へのアクセス
Javaスクリプト、Flashおよび他のスクリプトを使用してファイルをアップロードすることは、多くの場合、セキュリティ上のリスクがあると考えられます。ユーザセッションに使用する基本的なSCORMパッケージでさえ、HTMLおよびJavaスクリプトにより構成されるため、残念ながら、私たちはこれらのリスクを教師ロールから取り除くことはできません。
ブラウザは、1つのサーバから来るコンテンツすべてを信頼します。また、私たちのコースまたはデータの発信元に関して、知ることはありません。サーバにファイルがアップロードされた場合、それらはサーバアプリケーションの一部となります。サーバに保存されている必要なコード、不必要なコードを区別することは不可能です。
教師アクセスを学生に与えることはできないため、危険なケイパビリティを持った教師すべてを信頼すべきです。理論的には、教師は、管理者アクセスを取得するため、XSSアタックを使用することはできます。
技術的には、教師が他のユーザを攻撃できないシステムを開発することは可能ですが、すべてのJavaスクリプト、Flash、SCORM、Java、HTMLフォーム、SVG等の使用を阻むことになります。
学生
学生はコースに受講登録しますが、信頼されたユーザというわけではありません。学生には、次の権限が必要です:
- フォーマットされたテキストを埋め込みイメージおよび添付ファイルと共に投稿する
- バイナリドキュメントをアップロードする
アップロードされたファイルは、同じサーバよりブラウザで直接開かれるべきではありません。代わりに、ファイルを異なるドメインから提供するか、ファイルを開く前に、サーバがファイルのローカルハードドライブへのダウンロードを強制させる必要があります。異なるドメインからの信頼されないファイルを提供する機能は、Moodle 2.0に実装されます。
学生が送信したテキストすべては、すべてのページに表示される前にサニタイズされます。これにより、他のユーザによるXSS攻撃を防ぐことができますが、同時にFlash、Javaスクリプト、SVGおよび他のHTMLスクリプトを使えないようにしてしまいます。HTMLのクリーニングには、2つの方法があります - 信頼性の薄いブラックリスティング (KSES) およびさらに堅牢なホワイトリスティング (HTML Purifier) です。
ゲスト
セキュリティ上の理由から、Moodleサイトに登録していないユーザは、ファイルをアップロードすること、データベースに保存されるテキストを送信することは、許可されていません。ゲストユーザは、他のユーザへのスパム送信、HTMLクリーニングルーチンの脆弱性攻撃、他の脆弱性を悪用したり、ソーシャル・エンジニアリングをベースとした攻撃を試みることができます。
Eメール経由でのユーザ登録を有効にしているサイトは、スパムおよび他のタイプの攻撃を防ぐよう、十分な注意が必要です。
ケイパビリティリスク
Moodleは非常に柔軟なシステムであり、管理者は複数のロールを定義することができます。それぞれのロールは、システムレベルで定義された一連のケイパビリティであり、ロールは、低いレベルのコンテクストでのオーバーライドにより、修正することができます。リスクは、それぞれのケイパビリティの記述であり、管理者は、信頼できるユーザのみが潜在的に危険なケイパビリティを持てるよう確認すべきです。
セキュリティ脆弱性の一般的なタイプ
- Unauthenticated access
- Unauthorised access
- Cross-site request forgery (XSRF)
- クロスサイトスクリプティング (Cross-site scripting) (XSS)
- SQLインジェクション
- Command-line injection
- Data-loss
- Confidential information leakage
- Configuration information leakage
- Session fixation
- Denial of service
- Brute-forcing login
- Insecure configuration management
- Buffer overruns, and other platform weaknesses
- Social engineering
ガイドラインの要約
ユーザを認証する
- 非常に少ない例外として、可能な限りトップの近くで、すべてのスクリプトは、require_login または require_course_login をコールする必要があります。
コースおよびモジュールアクセスを確認する
- すべてのコースエリアは、正しい$courseパラメータを使用して、require_loginまたはrequire_course_loginにより保護される必要があります。
- すべてのモジュールエリアは、正しい$courseおよび$cパラメータを使用して、require_loginまたはrequire_course_loginにより保護される必要があります。
パーミッションをチェックする
- ユーザが何かを閲覧または何かをする前に、has_capability または require_capabilityをコールしてください。
- ケイパビリティは、適切なリスクにより注釈を付けてください。
- 適切な場合、グループによって、ユーザに表示される内容が制限されます。
ユーザからのインプットすべてを信用しない
- それぞれのフィールドに要求される適切なsetTypeを使って、可能な限りmoodleformを使用してください。
- 処理を実行する前、セッションキーおよびPOSTキーでの処理を確認するため、is_post_with_sesskeyを使用してください。
- Moodle 1.9では、代わりにdata_submitted() および confirm_sesskey()を使用してください。
- 大量のデータを削除する前、確認ステップを入れてください。
- moodleformを使用しない場合、適切なPARAM_...タイプおよびoptional_paramまたはrequired_paramを使用してください。
- 直接、$_GET、$_POSTまたは$_REQUESTにアクセスしないでください。
- 簡単に見つけやすいように、optional_paramおよびrequired_paramコールのグループは、スクリプトのトップに置いてください。
同様に、RSSフィードのような他の外部リソースのデータを使用する前にクリーニングします。
出力前にデータをクリーニングおよびエスケープする
- プレインテキストコンテンツの出力には、s または p を使用してください。
- multi-lang spanのような最小限のHTMLコンテンツの出力には、format_stringを使用してください (例 コースおよび活動名)。
- 他のすべてのコンテンツを出力するには、format_textを使用してください。
- コンテンツの入力にケイパビリティRISK_XSSを必須とする場合 (例 ウェブページリソース)、$options->nocleanのみ使用してください。
- Moodle 2.0以前のバージョンでは、optional_paramまたはrequired_paramからの入力内容がデータベースに保存されるのではなく、直接表示される場合、「stripslashes」または「stripslashes_recursive」を適用してください。
- Javaスクリプトに向かうデータは、$PAGE->requires->data_for_js (Moodle 2.0) または addslashes_js (Moodle 1.9) を使用して、エスケープしてください。
詳細は、開発:アウトプット関数をご覧ください。
データベースに保存する前にデータをエスケープする
- XMLDBライブラリを使用してください。このライブラリは、ほとんどのエスケープに関する問題に対応します。
- あなたがカスタムSQLコードを使用する必要がある場合、クエリに値を入れるには、プレスホルダを使用してください。
- Moodle 2.0以前のバージョンでは、あなたは、ストリングを連結してSQLを作成する必要がありました。SQLインジェクションに対する脆弱性を防ぐため、引用値には特に十分注意する必要があります。
- Moodle 2.0以前のバージョンでは、データベースから読み込まれるデータは、データベースに下記戻される前に、「addslashes」または「addslashes_object」を適用する必要がありました (Moodle 2.0コードでは、addslashesは使用されません)。
- Moodle 2.0において、変数は固定変数を通して、データベースクエリに渡される必要があります。
シェルコマンドで使用する前にデータをエスケープする
- 可能な限り、シェルコマンドの実行を避けてください。
- PHPライブラリがある場合、代わりに使ってください。
- あなたがシェルコマンドの使用を避けられない場合、escapeshellcmd または escapeshellarg を使用してください。
すべてのリクエストをログに記録する
- すべてのスクリプトでは、必ずadd_to_logをコールしてください。
他の優れた実践
... セキュリティに関する助けとなるもの。
- あなたのコードを美しく構築して、グローバル変数の使用を最小限にしてください。これにより、データフロー、つまりセキュリティに関して、検証がより簡単になります。
- あなたが最初に使用する前、オブジェクト ($x = new stdClass;) および配列 ($x = array()) を初期化してください。
- すべての入力フィールドに関して、巧妙な入力により、すべての場所で正しい回数のエスケープおよびエスケープ解除が実施されているかどうかテストしてください。そして、ユニコード文字が文字化けしていないかどうかもテストしてください。ユニコード文字に関する私の標準的な入力は次のとおりです:
< > & < > & ' \' 碁 \ \\