PHPの低レベルネットワークプログラミングインターフェイスを使用する場合、 socket_accept()関数は、インバウンド接続の処理における重要なステップです。通常、 Socket_Create() 、 socket_bind() 、 socket_listen()などの関数と組み合わせて使用して、サーバー側のソケットを構築します。このプロセスは非常に基本的ですが、安全リスクにも満ちています。特にクライアントの接続を受け入れた後、不適切に処理した場合、違法なデータインジェクション攻撃に苦しむのは非常に簡単です。
この記事では、socket_accept()を使用する際に違法なデータインジェクションを防ぐためのいくつかの効果的な方法を紹介します。
socket_read()を使用してクライアントから送信されたデータを読み取るときは、バッファオーバーフローまたは過度のデータパケットを防ぐために最大読み取り長を設定してください。
$buffer = socket_read($clientSocket, 2048, PHP_NORMAL_READ);
最大読み取り長は2048バイトに設定されています。クライアントがこの長さを超えるデータを送信しようとすると、自動的に切り捨てられ、データ注入のリスクが減ります。
データを読んだ後、フォーマットチェックサムの違法文字フィルタリングをすぐに実行する必要があります。正規表現またはPHPビルトインフィルタリング関数を使用して、データを処理することをお勧めします。例えば:
$input = trim($buffer);
if (!preg_match('/^[a-zA-Z0-9\s]+$/', $input)) {
socket_write($clientSocket, "違法投入!\n");
socket_close($clientSocket);
exit;
}
この方法では、制御文字、特別なシンボル、または悪意のあるコマンドがさらに処理されるのを防ぐことができます。
サーバーとクライアントがカスタムプロトコルを介して通信した場合は、明確なメッセージ形式と境界を設計してください。簡単な例を挙げると、クライアントは特定のキーワードから始まるパケットを送信する必要があることを指定できます。
if (strpos($input, 'CMD:') !== 0) {
socket_write($clientSocket, "プロトコル形式エラー!\n");
socket_close($clientSocket);
exit;
}
このように、ほとんどの無効または悪意のあるリクエストは、プロトコルレベルでブロックできます。
クライアントが長い間接続を維持し、悪意のあるデータを継続的に送信するのを防ぐために、各ソケットに合理的なタイムアウトを設定することをお勧めします。
socket_set_option($clientSocket, SOL_SOCKET, SO_RCVTIMEO, ["sec"=>5, "usec"=>0]);
クライアントが5秒以内にデータを送信しない場合、サーバーは自動的に切断されます。このアプローチは、潜在的なサービス拒否(DOS)攻撃を効果的に軽減できます。
違法データを複数回送信するクライアントIPの場合、ブロッキングまたは一時的なブロッキングを考慮する必要があります。同時に、各違法データの試みを記録することは、後の攻撃トレースとポリシーの調整にも重要です。
file_put_contents('logs/illegal_access.log', $_SERVER['REMOTE_ADDR'] . " - $input\n", FILE_APPEND);
ファイアウォールルールを組み合わせて、悪意のあるリクエストのソースIPを自動的にブロックできます。
以下は、上記の保護対策を統合する基本的なソケットサーバーの実装です。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 12345);
socket_listen($socket);
while (true) {
$clientSocket = socket_accept($socket);
if ($clientSocket === false) {
continue;
}
socket_set_option($clientSocket, SOL_SOCKET, SO_RCVTIMEO, ["sec"=>5, "usec"=>0]);
$buffer = socket_read($clientSocket, 2048, PHP_NORMAL_READ);
$input = trim($buffer);
if (!preg_match('/^[a-zA-Z0-9\s]+$/', $input)) {
socket_write($clientSocket, "違法投入!\n");
file_put_contents('/var/log/socket_illegal.log', "違法アクセスの試み: $input\n", FILE_APPEND);
socket_close($clientSocket);
continue;
}
// サンプル処理ロジック
socket_write($clientSocket, "訪問してください m66.net Socket 仕える!\n");
socket_close($clientSocket);
}
PHPで直接ソケットプログラミングを使用することは強力ですが、開発者はデータ通信セキュリティを完全に理解する必要があります。読み取り長を制限し、入力データの検証、通信プロトコルの定義、タイムアウトの設定、ログの記録により、 socket_accept()を使用する場合の違法データインジェクションのリスクを大幅に削減できます。
常に覚えておいてください:クライアントと対話するデータのすべてのバイトは、潜在的な攻撃ベクトルになる可能性があり、防御はコードの最初の行から始まります。