web-dev-qa-db-ja.com

PHP and MySQL-ソースコードでパスワードを回避する方法?

小さなPHP MySQL データベースにデータを保存するアプリケーションがあります。現在、ユーザー名/パスワードはPHPコードでハードコーディングされています。たとえば、コードはリポジトリでも利用できるため、私はあまり好きではありません。

私が持っている最良のアイデアは、データをコードから構成ファイル(リポジトリから除外)に移動し、何らかの方法でエンコードすることです。したがって、直接読み取ることはできません(難読化)。問題を解決するためのより使いやすい方法はありますか?

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) { 
    die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');

範囲:堅牢で使いやすいソリューションを確立したい。合理的なセキュリティが必要ですが、ここでは機密性の高いデータを扱っていません。

注:mysql_connect関数の使用は推奨されなくなりました。スタックオーバーフローの質問なぜmysql_を使用すべきでないのかPHPの関数?*。コード例を変更することもできましたが、いくつかのコメントがこれを参照しているため、変更しませんでした。ただし、質問の元の性質は引き続き有効です。

111
Horst Walter

あなたが言ったように、最も簡単な方法は、構成ファイルを使用することです。

多くのフレームワークはこれを使用します( ZendCakePHPKohana など)および最も一般的な方法です(web.configファイルを使用するASP.NETなどの非PHP環境でも)。これにより、サイトのファイルをコピーするだけで、環境から環境に設定値をコピーすることもできます。これは、サーバーセットアップ環境変数(非常にすばやく失われ、忘れられる可能性があります)に依存するよりも有利です。

パスワードは誰もがアクセスできるファイルではないため、パスワードの難読化について心配する必要はありません。Webにアクセスできないようにする必要があります。これが意味することは、a)Webサーバーに設定ファイルを提供しないように指示することです( [〜#〜] iis [〜#〜] は既にこれを行います) web.configファイルを作成し、コンテンツの代わりにHTTP 404.8ステータスを提供します)またはb)Web提供ディレクトリの外部に移動します。誰かがあなたの設定ファイルを見ることができるなら、それはあなたのソースコードにあるよりも悪いです。

また、構成ファイルのベース(空/デフォルト)バージョンを用意し、環境ごとに分離することをお勧めします。これにより、本番、開発、およびテストプラットフォーム用に異なる構成ファイルを作成できます。

環境変数は、これらの環境を区別するための最も一般的な方法で、次のコードのようなものです。

// Check if it's been set by the web server
if (!empty($_ENV['ENVIRONMENT'])) {
    // Copy from web server to PHP constant
    define('ENVIRONMENT', $_ENV['ENVIRONMENT']);
}

if (!defined('ENVIRONMENT')) {
    // Default to development
    define('ENVIRONMENT', 'development');
}

// Load in default configuration values
require_once 'config.default.php';

// Load in the overridden configuration file for this environment
require_once 'config.' . ENVIRONMENT . '.php';

かなり一般的なもう1つの方法は、XML構成ファイルを使用し、必要に応じて必要な値のみを読み込むことです(構成ファイルのキャッシュされたコピーをメモリに保存します)。これは、PHPファイルを任意に含めることを許可するのではなく、特定の値のみをロードするように非常に簡単に制限できます。方向。

[〜#〜] vcs [〜#〜] がファイルを無視することを望むでしょう。一方、ファイルのスケルトン、または妥当なデフォルトのスケルトン(もちろん、後者はログインデータには適用されません)をバージョン管理したい場合があります。これに対処する一般的な方法は、チェックインされたテンプレート構成ファイルを使用することです。インストール手順により、そのファイルが実際の構成ファイルの場所にコピーされ、そこでカスタマイズされます。これは、手動または自動のプロセスです。

(主な質問とは多少関係ありませんが、環境に定数を導入すると、ライブ [〜#〜] smtp [〜#の代わりに偽メールの実装を延期するなど、他のクールな機能を実行できます〜] 1つですが、もちろんこれは構成ファイルでも実行できます)

68
Rudi Visser

Apacheを使用している場合は、仮想ホスト構成に情報を保存するための1つの非常に素晴らしいソリューション

SetEnv  MYSQL_USER     "xx"
SetEnv  MYSQL_PASSWORD "y2wrg435yw8"

データは、コードで使用するために$_ENV[]を使用して簡単にフェッチできます。

46
hank

他の人が述べたように、それをソース管理外の別の構成ファイルに入れます(明らかに、これはソース管理下のコードで言及されます)。

また、ディレクトリが誤って公開された場合にファイルがダウンロードされないことを意味するため、config.iniではなくconfig.phpという名前を付けることをお勧めします、むしろ何も返しません。

11
acutesoftware

12factor の方法が価値があると思う場合、環境に設定を保存することをお勧めします。

これには、テスト時または非実稼働環境でまったく同じコードを記述できるという利点があります。データベースなどを変更する(または必要とする)場合、コードを変更する必要はありません。環境変数を変更するだけで準備完了です。

5
Wayne Werner

私がすることは、config.php.distのようなリポジトリにサンプルの設定ファイルのみを保存し、実際のconfig.phpをバージョン管理下に置かないことです。

2
Serge Kuharev

パスワードをコードから構成ファイルに移動することをお勧めします。これにより、パスワードがリポジトリーに存在しなくなります。構成ファイルを暗号化するという考え方は、構成ファイル+ PHPを解読するコードを持っている人が常にコードを実行し、クリアテキストのパスワードを取得できるためです。構成ファイルにパスワードをプレーンテキストとして保持し、構成ファイルを不正アクセスから保護する方法を検討することをお勧めします。

2

良い質問。最も機密性の高い部分(例:キー/パスワード)を環境変数として移動することもできますが、その場合は問題がサーバー構成に遅延します(おそらくリポジトリにもあります)。

また、パスワードを少なくし、代わりにファイアウォールで保護することにより、データベースなどのパスワードを回避することもできます。これらはどれも完璧なソリューションではありませんが、私が知っているアプローチです。

2
troelskn

この問題はすべてここにはありません。リポジトリを共有している場合は、パスワードと構成をハードコーディングする必要はおそらくないでしょう。代わりにデフォルトの1つを提供する必要があります。

Host: localhost
user: root
pass: root
name: db

本当に必要な場合は、.iniファイルですが、ソースコードで設定されている配列と比較して非常に遅い可能性が高く、実際にはそれほど意味がありません。

覚えておいてください:あなたが信頼できる唯一のものはあなたのソースコードです、彼らがそれを手に入れることができれば、とにかくあなたは台無しにされます。

1
Shoe

関数parse_ini_fileを使用して、設定iniファイルをいつでも作成できます。

1
Dawid Sajdak