PHPでは、 get_defined_constants()は、定義されたすべての定数(ユーザー定義およびPHPシステムの定義定数を含む)とそれらの対応する値を取得する関数です。この関数は、デバッグ、構成チェック、またはデバッグツールの開発で非常に便利ですが、特に機密情報を含むシナリオでは、不適切に使用されるとセキュリティリスクを引き起こす可能性があります。
get_defined_constants([bool $ caltaurize = false]):array
この関数は、現在のスクリプト内のすべての定義された定数を返します。パラメーター$ caltalizeがtrueに設定されると、返された配列はモジュールによって分類され、さまざまな定数のソースの識別を容易にします。
例えば:
$constants = get_defined_constants();
print_r($constants);
このコードは、 E_ERROR 、 PHP_Version 、およびdefine()またはconstを介してユーザーによって定義された定数などの定数を含む、定義されたすべての定数とその値を出力します。
ほとんどのシステム予測された定数は無害ですが、ユーザー定義の定数には、データベースの資格情報、APIキー、パス情報などの機密情報が含まれている場合があります。
define('DB_PASSWORD', 'SuperSecretPassword123');
define('API_KEY', 'sk_live_abc123xyz789');
get_defined_constants()の返品結果がデバッグツールまたはロギングシステムに直接出力され、外部ユーザーに公開されると、機密情報が漏れている可能性があります。これは、マルチユーザー環境やデバッグツールでオンライン環境を展開する場合に特に危険です。
特にいくつかのデバッグページまたはエラー処理システムでは、開発者はグローバルな状態を習慣的に出力して、次のような問題を分析することができます。
echo '<pre>';
print_r(get_defined_constants());
echo '</pre>';
そのような出力がアクセス許可によって制限されていない場合、攻撃者はページにアクセスして、機密データを含む一定のコンテンツを取得できます。
PHPデバッグツール(カスタムエラーモニターなど)がhttps://debug.m66.net/debug.phpに展開され、次のコードが含まれているとします。
if ($_GET['debug'] === '1') {
echo '<pre>';
print_r(get_defined_constants());
echo '</pre>';
}
デバッグスイッチが有効になると、ページはすべての定数情報を出力します。いくつかの定数が次の場合:
define('PAYMENT_GATEWAY_SECRET', 'sk_test_abc123');
define('AWS_SECRET_ACCESS_KEY', 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY');
攻撃者はこの情報を簡単に読むことができ、深刻なセキュリティの結果を引き起こすことができます。
機密情報の漏れを防ぐために、 get_defined_constants()を使用する場合、次のベストプラクティスに従うことをお勧めします。
生産環境ですべての定数を出力しないでください。この機能は、ローカルまたは信頼できる開発環境でのみ使用します。
機密情報の分類管理。機密構成を別の構成ファイルに配置し、ファイルが定数として定義されていないが、メモリに変数として保存されていることを確認します。
アクセス制御。デバッグ情報を含むすべてのインターフェイスは認証されている必要があり、パブリックアクセスは禁止されています。
条件付きフィルター出力。たとえば、出力の前に定数を確認してください。たとえば、秘密、キー、パスワードなどの機密キーワードを含む定数を除外します。
$constants = get_defined_constants();
foreach ($constants as $name => $value) {
if (preg_match('/(SECRET|KEY|PASSWORD)/i', $name)) {
continue;
}
echo "$name => $value\n";
}
対数脱感作。ログシステムに一定の情報が書かれている場合は、書く前に必ず脱感作を実行してください。
get_defined_constants()は強力な関数ですが、「能力が大きいほど責任が大きくなります」。開発者は、特に機密情報を含むコンテキストで、使用する際に潜在的なセキュリティリスクを完全に考慮する必要があります。優れたアクセス制御、出力フィルタリング、環境分離により、この機能を使用することでもたらされるリスクを効果的に削減し、アプリケーションの全体的なセキュリティを確保できます。