Lorsque vous utilisez l'interface de programmation réseau de bas niveau de PHP, la fonction socket_accept () est une étape importante pour gérer les connexions entrantes. Il est généralement utilisé en conjonction avec des fonctions telles que socket_create () , socket_bind () et socket_listten () pour créer une prise côté serveur. Bien que ce processus soit très basique, il est également plein de risques de sécurité. Surtout après avoir accepté les connexions des clients, si elle est traitée mal, il est très facile de souffrir d'attaques illégales d'injection de données.
Cet article introduira plusieurs moyens efficaces de prévenir l'injection de données illégales lors de l'utilisation de socket_accept () .
Lors de la lecture des données envoyées par le client à l'aide de socket_read () , assurez-vous de définir la longueur de lecture maximale pour empêcher le débordement de tampon ou les paquets de données excessifs:
$buffer = socket_read($clientSocket, 2048, PHP_NORMAL_READ);
La longueur de lecture maximale est définie sur 2048 octets. Si le client essaie d'envoyer des données dépasse cette longueur, elle sera automatiquement tronquée, ce qui réduit le risque d'injection de données.
Après avoir lu les données, le filtrage des caractères illégaux de somme de contrôle du format doit être effectué immédiatement. Il est recommandé d'utiliser des expressions régulières ou des fonctions de filtrage intégrées PHP pour traiter les données. Par exemple:
$input = trim($buffer);
if (!preg_match('/^[a-zA-Z0-9\s]+$/', $input)) {
socket_write($clientSocket, "Entrée illégale!\n");
socket_close($clientSocket);
exit;
}
Cette méthode peut effectivement empêcher les données avec des caractères de contrôle, des symboles spéciaux ou des commandes malveillantes d'être traitées davantage.
Si le serveur et le client communiquent via un protocole personnalisé, assurez-vous de concevoir un format de message et une limite clairs. Pour donner un exemple simple, il peut être spécifié que le client doit envoyer un paquet qui commence par un certain mot-clé:
if (strpos($input, 'CMD:') !== 0) {
socket_write($clientSocket, "Erreur de format de protocole!\n");
socket_close($clientSocket);
exit;
}
De cette façon, la plupart des demandes invalides ou malveillantes peuvent être bloquées au niveau du protocole.
Pour empêcher les clients de maintenir les connexions pendant longtemps et d'envoyer en continu des données malveillantes, il est recommandé de définir un délai d'expiration raisonnable pour chaque prise:
socket_set_option($clientSocket, SOL_SOCKET, SO_RCVTIMEO, ["sec"=>5, "usec"=>0]);
Si le client n'envoie aucune donnée dans les 5 secondes, le serveur se déconnecte automatiquement. Cette approche peut atténuer efficacement les attaques de déni de service (DOS).
Pour les IP client qui envoient des données illégales plusieurs fois, le blocage ou le blocage temporaire doit être pris en compte. Dans le même temps, l'enregistrement de chaque tentative de données illégaux est également cruciale pour le traçage des attaques ultérieur et les ajustements de politique:
file_put_contents('logs/illegal_access.log', $_SERVER['REMOTE_ADDR'] . " - $input\n", FILE_APPEND);
Vous pouvez combiner des règles de pare-feu pour bloquer automatiquement l'IP source des demandes malveillantes.
Ce qui suit est une implémentation de base de serveur de socket qui intègre les mesures de protection ci-dessus:
$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, "Entrée illégale!\n");
file_put_contents('/var/log/socket_illegal.log', "Tentative d'accès illégal: $input\n", FILE_APPEND);
socket_close($clientSocket);
continue;
}
// Exemple de logique de traitement
socket_write($clientSocket, "Bienvenue à visiter m66.net Socket Servir!\n");
socket_close($clientSocket);
}
Bien que l'utilisation de la programmation de socket directement dans PHP soit puissante, elle oblige également les développeurs à comprendre pleinement la sécurité de la communication des données. En limitant la longueur de lecture, en vérifiant les données d'entrée, en définissant les protocoles de communication, en établissant des délais d'expiration et en enregistrant les journaux, le risque d'injection de données illégale lors de l'utilisation de socket_accept () peut être considérablement réduit.
N'oubliez pas: chaque octet de données qui interagit avec le client peut être un vecteur d'attaque potentiel, et la défense commence par la première ligne de code.