いくつかの SQL クエリが使用されているプロジェクトを開発しました。セキュリティを強化するために、いくつかのクエリを監視したいと考えています。したがって、すべてのクエリを最初に関数に渡す必要があります。クエリが多すぎるため、戻ってすべてのファイルとクエリを編集することはできません。クエリが mysql サーバーに送信される前にトラップできる方法はありますか?
2 に答える
これを実現するには、使用しているものに応じて 4 つの方法がありますが、最後の方法がはるかに信頼性が高くなります。
一般的なクエリ ログ
MySQL はmysqld
、一般的なクエリ ログを介して、プロセスが行っているほぼすべてをログに記録するメカニズムを提供します。質問で説明したように、おそらく永続的な接続がないため、次のいずれかを行う必要があります。
mysqld
プロセスの開始時に MySQL の一般的なクエリ ログを有効にします。--log[=file_name]
- でグローバル/セッション変数を設定し
SET GLOBAL general_log = 'ON'
ます。
- でグローバル/セッション変数を設定し
一般的なクエリ ログの詳細については、MySQL 5.1 リファレンス マニュアルを参照してください。
を使用してsed
(または手動で!)
この手法では、新しい関数を作成し、すべてのmysqli_*
関数呼び出しの名前を変更して別の関数を呼び出します。
新しく作成した関数の名前がであると仮定するとproxy_query()
、 を使用sed
してすべてのファイルをトラバースし、それらを自動的に変更できます。
sed i '.bck' 's/mysqli_query/proxy_query/'
-i
パラメータは、ファイルをその場で編集する必要があること、および元のファイルのコピーを作成して拡張子.bck
を追加する必要があることを指定します。
runkit
拡張子_
ここで私が素朴であること、およびこの特定の拡張機能を以前に使用したことがないことを認めなければなりませんが、この PECL 拡張機能を使用して関数の名前を変更することは可能です。この拡張機能の要件はこちらで確認できます。PHP にはバンドルされていないことに注意してください。
上記と同様に、すべての呼び出しが通過するプロキシ関数を作成できます。とも呼ばれているとしましょうproxy_query
。使用法は次のようになります。
// rename the function (a very bad idea, really!)
runkit_function_renam('mysqli_connect', 'proxy_super');
function mysqli_query($query, $resultmode = MYSQLI_STORE_RESULT)
{
// do something with the SQL in $query
// .. and call mysqli_query, now proxy_super
return proxy_super($query, $resultmode);
}
ここで、この方法は非常に推奨されないことに注意する必要があります。デフォルトの PHP 関数を設定する必要はありません。
Pdo/OO-mysqli の使用
これは最も単純な手法であり、おそらく最も信頼できる手法でもあります。すでに Pdo を使用している場合は、単純に\Pdo
クラスを拡張できます。mysqli
MySQL Improvement( )で同様のアプローチを使用できます。
class MyPdo extends \Pdo
{
public function query($query [, ... ])
{
// do something with $query
return parent::query($query [, ... ]);
}
}
また、これは Pdo を使用している場合にのみ機能し、Pdo
オブジェクトのインスタンス化を変更して独自のクラスに上書きできる場合にのみ機能することに注意してくださいMyPdo
。\Pdo
クラスとその子の詳細については、マニュアルを参照してください。
SQL プロファイラーを使用して着信クエリを監視する場合は、単一の関数またはプロシージャを介してすべてを渡すことなく、SQL 内部で何が起こっているかに関する情報を収集する優れた方法です。