https://www.clamav.net/ Кейс: Берем проект, где пользователи часто загружают файлы. Как добавить проверку на вирусы?

  • https://www.clamav.net/ - ставим, запускаем как сервис. Можно, конечно, запускать каждый раз, но тогда будет происходить долгая инициализация базы (база вирусов будет загружать в оперативную память).
  • Из php цепляемся к сокету антивируса и делаем примерно следующее: php

/**

  • Проверяет файл на вирусы через запущенный демон ClamAV (clamd).
  • @param string $filePath Полный путь к временному файлу на сервере.
  • @return bool True, если файл чист. False, если обнаружен вирус или произошла ошибка. */ function isFileSafe(string $filePath): bool { if (!file_exists($filePath)) { return false; }

// Дефолтный путь к сокету в Ubuntu/Debian $socketPath = 'unix:///var/run/clamav/clamd.ctl';

// Подключаемся к демону ClamAV $socket = @stream_socket_client($socketPath, $errno, $errstr, 2);

if (!$socket) { // Если антивирус лежит, логируем ошибку. // В продакшене лучше заблокировать загрузку, если безопасность в приоритете. error_log("ClamAV connection error: $errstr ($errno)"); return false; }

// Команда SCAN <путь_к_файлу требует, чтобы у пользователя clamav // были права на чтение проверяемой директории (например, /tmp) fwrite($socket, "SCAN " . $filePath . "n");

// Получаем ответ от демона $response = fgets($socket); fclose($socket);

// Ответ в случае успеха: "/tmp/phpXYZ: OK" // Ответ в случае вируса: "/tmp/phpXYZ: Eicar-Signature FOUND" if (str_contains($response, 'OK')) { return true; }

error_log("Virus detected or ClamAV error: " . trim($response)); return false; }

// === Пример обработки загрузки === if ($SERVER['REQUEST_METHOD'] === 'POST' && isset($FILES['user_file'])) { $tmpPath = $_FILES['user_file']['tmp_name'];

if (isFileSafe($tmpPath)) { // Файл безопасен, перемещаем в постоянное хранилище move_uploaded_file($tmpPath, DIR . '/uploads/' . basename($FILES['user_file']['name'])); echo "Файл успешно и безопасно загружен!"; } else { // Вирус обнаружен! Временный файл $FILES удаляется автоматически в конце скрипта http_response_code(400); echo "Ошибка: Файл заблокирован системой безопасности."; } }