セキュリティ

このページでは、ウェブセキュリティに関するいくつかの「ベストプラクティス」と、 CodeIgniter の内部のセキュリティ機能の詳細について説明します。

注釈

セキュリティ上の問い合わせ先を探してここに来た場合は、 Contribution Guide <../contributing/index> をご参照ください。

URI セキュリティ

CodeIgniter では悪意のあるデータがアプリケーションに渡る可能性を最小限にするために、 URI 文字列に使用できる文字に関してかなり限定しています。 URI は以下のもののみ 含むことができます:

  • 英数字テキスト(ラテン文字のみ)
  • チルダ: ~
  • パーセント記号: %
  • ピリオド: .
  • コロン: :
  • アンダースコア: _
  • ダッシュ: -
  • スペース

register_globals

システムの初期化時、 $_GET$_POST$_REQUEST$ _COOKIE 内に見つけられる変数でグローバル変数のものはすべて unset されます。

この unset ルーチンは register_globals = off と同じ効果です。

display_errors

本番環境では一般的に PHP のエラー報告を「無効」にすることが望ましいです、 内部の display_errors フラグを 0 に設定することにより行われます。 これは素の PHP エラーを出力として書き出されることを無効にします。 機密情報が潜在的に含まれているかもしれないからです。

CodeIgniter の ENVIRONMENT 定数をindex.php で 「 production 」の値に設定すると、これらのエラーをオフにします。 開発モードでは「 development 」の値を使用することをおすすめします。 環境の区別についての詳しい情報は 複数環境への対応 ページにあります。

magic_quotes_runtime

magic_quotes_runtime ディレクティブはシステムの初期化中にオフにされます。 そのため、データベースからデータを取得するときに スラッシュを除去する必要はありません。

ベストプラクティス

あらゆるデータについてアプリケーションに受け入れる前に、それがフォーム送信からの POST データであれ、 COOKIE データであれ、 URI データであれ、 XML-RPC データであれ、 または SERVER 配列でさえも、つぎの 3 段階のアプローチを 実践することが推奨されます:

  1. 正しい型、長さ、大きさ等に一致していることを確認するために、 データを検証する
  2. それが汚染されているかのように、データをフィルタリングする
  3. データベースにそれをサブミットするか、 それをブラウザに出力する前にデータをエスケープする

CodeIgniter はこのプロセスを支援する以下の機能とヒントを 提供します:

XSS フィルタリング

CodeIgniter にはクロスサイトスクリプティングフィルターが付属しています。 このフィルタは、データに悪意のある JavaScript を埋め込むために一般的に使用される技術、 またはクッキーをハイジャックしようとするなど、 悪さしようとするコードを探し出します。 XSS フィルターは ここ で説明されています。

注釈

XSS フィルタリングは 出力でのみ実行 するべきです。 入力データをフィルタリングすると望ましくない方法でデータを変更することになるかもしれません。 パスワードから特殊文字を取り除いてしまったりなど、 セキュリティを向上させるどころか低下させます。

CSRF 保護

CSRF は クロスサイトリクエストフォージェリの略で、 無意識のうちに犠牲者にリクエストを送信させる攻撃方法です。

CodeIgniter では CSRF の保護をすぐにお使いいただけます、 自動的にすべての非 GET HTTP リクエストをトリガーとしますが、 サブミットフォームを正しい方法で作成することが必要になります。 これは セキュリティライブラリ ドキュメントで説明されています。

パスワードの取り扱い

アプリケーションで適切にパスワードを扱うことは 重要事項 です。

残念ながら、多くの開発者はどう取り扱えばよいかを知らず、 そしてウェブは賞味期限切れないし間違ったアドバイスであふれており、助けになりません。

私たちはあなたの助けとするため、やるべきこと、避けるべきことを合わせたリストを提供したいと思います。 どうぞ下記をお読みください。

  • プレーンテキスト形式でパスワードを保存 し な い で ください。

    必ずパスワードを ハッシュ してください。

  • パスワードを格納するためにBase64または類似のエンコーディングを使用 し な い で ください。

    これはプレーンテキストとして保存すると同程度のものです。本当に。 エンコーディング ではなく ハッシュ してください。

    符号化と、そして暗号化も、双方向の処理です。 パスワードはその所有者だけが知るべき秘密であり、 そのため処理は一方向にだけ行われるものでなければなりません。ハッシュがそれです―― 未ハッシュまたは逆ハッシュというものは 存在せず 、しかし復号化や暗号解除は存在します。

  • MD5またはSHA1のような、弱いまたは壊れたハッシュアルゴリズムを使用 し な い で ください。

    これらのアルゴリズムは古く、欠陥があることが証明され、 そもそもがパスワードハッシュのためには設計されていません。

    また、独自のアルゴリズムを考案 し な い で ください。

    BCrypt のような強力なパスワードハッシュアルゴリズムのみを使用してください、 これは PHP の パスワードハッシュ 関数で使用されています。

    PHP 5.5 以降でない場合でもこれらを使ってください、 CodeIgniter は PHP 5.3.7 以上でそれらの関数を提供しています (その要件を満たしていない場合は――どうかアップグレードしてください)。

    もしあなたが本当に不運な人たちの一人で PHP のバージョンを十分新しいものにできないなら、 hash_pbkdf() <http://php.net/hash_pbkdf2> を使用してください、 これは互換性レイヤで提供しています。

  • プレーンテキスト形式でのパスワード表示、送信は絶対に し な い で ください!

    パスワードの所有者に対してでも、たとえ「パスワードを忘れたとき」機能を必要とする場合であっても、 かわりにランダムな新しい、ワンタイム(これも重要です)パスワードを生成し、 それを送信するだけにしてください。

  • ユーザのパスワードに不必要な制限を設定 し な い で ください。

    BCrypt(72 文字の制限があります)の以外のハッシュアルゴリズムを使用している場合、 DoS 攻撃を軽減するため、パスワードの長さに比較的高めの上限を設定する必要があります ――1024文字、としましょう。

    それ以外ではなんであれ、 パスワードにルールを強制するのは的を外しています。 文字数の下限や、または特殊文字セットを含むことができないようにするものです。

    これはセキュリティが改善するのではなく 低下 するばかりか、 それを行う理由が文字通りありません。ハッシュするのに技術的な制限や (実際的な)ストレージの制約はなにもありません、なにも!

入力データを検証する

CodeIgniter には フォームバリデーションライブラリ があり、 検証、フィルタリング、およびデータの準備を支援します。

しかしそれがあなたのユースケースでは機能しない場合でも、 常にすべての入力データを検証し、サニタイズしてください。 たとえば、数値文字列を入力として期待する場合、 is_numeric() または ctype_digit() を使ってチェックすることができます。 常にチェックを一定のパターンに絞り込むよう取り組んでください。

心得ておいてください、 $_POST$_GET 変数に限らず、 クッキー、ユーザーエージェント文字列および基本的に みずからのコードで直接作成されていないすべてのデータ が対象であることを。

データベースへの挿入前にすべてのデータをエスケープする

エスケープなしにデータベースに情報を挿入しないでください。 詳細については データベースクエリ で説明されているセクションを参照してください。

ファイルを隠す

もう一つの良いセキュリティプラクティスは、 index.php とサーバーの「 assets 」(例えば .js ファイル、CSSと画像ファイル) だけをサーバの ウェブルート ディレクトリ(最も一般的には「 htdocs/ 」という名前) の下に置くことです。ウェブからアクセスできるようにする必要があるファイルはこれらだけです。

それら以外の何かを訪問者から見えるようにすると、 スクリプトを実行するなど、潜在的に機密データにアクセスできるようになることを許すことになります。

その設定が許可されていない場合、それらのリソースへのアクセスを制限する .htaccess ファイルの利用を試みてください。

CodeIgniter ではディレクトリのすべてに index.html ファイルを置くことでこれらのデータを保護しようとしていますが、 これは本気の攻撃者に対しては不十分であることを 気に留めておいてください。