Статьи

ClamAV как валидационный фильтр в Zend Framework

Итак, вы достаточно комфортно используете Zend Framework, в частности, использование Forms. Наряду с этим у вас есть хорошие практические знания о том, как объединить множество стандартных валидаторов, таких как CreditCard , EmailAddress , Db_RecordExists и Hex , и стандартных фильтров, таких как Compress / Decompress , BaseName , Encrypt и RealPath . Но что вы делаете, когда возникает ситуация, которая выходит за рамки предварительно упакованных валидаторов и фильтров?

Допустим, вы хотите защититься от пользователей, загружающих, например, файлы, содержащие вирусы. Вам нужно написать собственный валидатор, который проверяет, что закачки не заражены. Сегодня я покажу вам, как это сделать — как написать новый фильтр проверки файлов для Zend Framework, который использует ClamAV, чтобы гарантировать, что загруженные файлы не содержат вирусов.

Добавление поддержки ClamAV в PHP

Сначала вам нужно установить поддержку ClamAV. Я основываю эту процедуру установки на Linux, в частности на Ubuntu. Если вы используете другой дистрибутив, вам может потребоваться настроить команды соответствующим образом. К сожалению, если вы используете Windows, вам нужно будет использовать виртуальное устройство на базе Linux или настроить виртуальную машину под управлением Linux, чтобы следовать, поскольку расширение php-clamav пока не поддерживает Windows.

Прежде чем пытаться установить ClamAv, убедитесь, что у вас установлены зависимости библиотеки. Вы также должны убедиться, что у вас установлен пакет PHP dev, чтобы phpize доступен phpize . Вы можете сделать это, выполнив следующую команду:

  msetter @ tango: ~ $ sudo apt-get установить php5-dev libclamav-dev clamav libclamav6 clamav-freshclam 

Как только вы установили зависимости, возьмите копию библиотеки php-clamav с sourceforge.net/projects/php-clamav и извлеките ее во временный каталог в вашей системе. Перейдите в каталог извлеченной библиотеки и выполните следующие команды:

  msetter @ tango: ~ / php-clamav $ phpize
 msetter @ tango: ~ / php-clamav $ ./configure --with-clamav
 msetter @ tango: ~ / php-clamav $ make 

Если все они выполняются без ошибок, вы найдете только что скомпилированный модуль в подкаталоге модулей. Скопируйте модуль в каталог, в котором находятся остальные ваши модули PHP. Ваша система может отличаться, но я смог сделать это с:

  msetter @ tango: ~ / php-clamav $ sudo cp modules / clamav.so / usr / lib / php5 / 20090626 + lfs / 

Затем вам нужно включить модуль в конфигурационном файле PHP. Это делается довольно просто, добавив следующую строку в php.ini и перезапустив Apache:

  расширение = clamav.so 

Наконец, либо запустите php -i из командной строки, либо выполните простой скрипт PHP, который содержит только вызов phpinfo() чтобы убедиться, что новое расширение включено. Вы должны увидеть результат, аналогичный приведенному ниже.

clamav extension in phpinfo output

Библиотека ClamAv поставляется с рядом констант и функций, но в этой статье я cl_scanfile() только на двух функциях cl_scanfile() и cl_pretcode() , так как все, что вам нужно сделать, — это сканировать загруженный файл и сообщать, что представляет собой вирус, если один найден. Для получения дополнительной информации о других доступных функциях посетите php-clamav.sourceforge.net .

Создание валидатора загрузки файлов

Теперь, когда расширение установлено и включено, давайте приступим к работе и создадим валидатор загрузки файлов Zend Framework ClamAV. Я предполагаю, что у вас уже есть рабочий проект Zend Framework, у которого включена поддержка модулей и он готов к работе. Добавьте поддержку новой библиотеки проверки, добавив следующую строку в файл application.ini :

  autoloaderNamespaces [] = "Common_" 

Затем в каталоге библиотеки вашего корня проекта Zend Framework создайте каталог Common/Validate/File и в нем файл с именем ClamAv.php со следующим содержимым:

 <?php class Common_Validate_File_ClamAv extends Zend_Validate_Abstract { } 

С этим ваш новый класс валидатора будет доступен для проекта.

Если вы не знакомы с валидаторами в Zend Framework, они довольно просты. Вы можете расширить их из Zend_Validate_Abstract или Zend_Validate_Interface . Для целей этого примера я основываю валидатор на первом. Учитывая это, вам нужно будет реализовать только два метода: конструктор и isValid() .

Конструктор должен проверить, загружено ли расширение ClamAv, поскольку оно не поставляется со стандартным дистрибутивом PHP.

Метод isValid() будет выполнять основную работу валидатора. Обычно метод проверяет некоторые входные данные и либо возвращает true, если проверка прошла успешно, либо устанавливает сообщение об ошибке в списке ошибок, который отображается впоследствии, и возвращает false, если проверка не удалась. В зависимости от конфигурации валидаторов вашей формы, возвращение false либо остановит валидацию формы в этой точке, либо позволит оставшимся валидаторам продолжить работу.

Заполните класс Common_Validate_File_ClamAv чтобы он выглядел так:

 <?php class Common_Validate_File_ClamAv extends Zend_Validate_Abstract { const STATUS_CLEAN = 0; const NOT_READABLE = "fileNotReadable"; const FILE_INFECTED = "fileInfected"; protected $_messageTemplates = array( self::FILE_INFECTED => "File '%value%' is infected", self::NOT_READABLE => "File '%value%' is not readable"); public function __construct() { if (!extension_loaded('clamav')) { throw new Zend_Validate_Exception( "ClamAv extension is not loaded"); } } public function isValid($value, $file = null) { if ($file === null) { $file = array("type" => null, "name" => $value); } if (!Zend_Loader::isReadable($value)) { return $this->_throw($file, self::NOT_READABLE); } $retcode = cl_scanfile($value, $virusname); if ($retcode !== self::STATUS_CLEAN) { printf("File path: %s | Return code: %s | Virus found name: %s", $value, cl_pretcode($retcode), $virusname); return $this->_throw($file, self::FILE_INFECTED); } return true; } protected function _throw($file, $errorType) { $this->_value = $file["name"]; $this->_error($errorType); return false; } } 

Сначала указывается набор констант класса, которые определяют статус возврата для шаблонов строк проверки на вирусы для пользовательских сообщений об ошибках. После этого конструктор проверяет доступность поддержки ClamAv. Если он недоступен, возникает исключение.

Метод isValid() проверяет, содержит ли входящий аргумент $value имя файла и доступен ли файл для чтения. Если это так, то cl_scanfile() функция cl_scanfile() . Код возврата из cl_scanfile() указывает, не содержит ли файл вирусов. Если нет, то имя вируса извлекается с помощью функции cl_pretcode() и информация cl_pretcode() на печать.

Метод _throw() заботится об установке соответствующей константы ошибки в классе и возврате false, чтобы указать, что проверка не удалась. Если это произойдет, сообщение об ошибке, связанное с константой, будет отображаться в форме загрузки с помощью декоратора ошибок в элементе ввода.

Тестирование валидатора

С написанным валидатором вам понадобится форма, чтобы использовать его и проверить, работает ли он. Либо вручную, либо с помощью zf.sh создайте новое действие в классе IndexController модуля по умолчанию и назовите его «fileUpload». Добавьте следующий код к нему:

 <?php class IndexController extends Zend_Controller_Action { ... public function fileUploadAction() { $form = new Zend_Form(); $form->setAction("/default/index/file-upload") ->setMethod("post"); $uploadFile = new Zend_Form_Element_File("uploadfile"); $uploadFile->addValidator(new Common_Validate_File_ClamAv()) ->setRequired(true) ->setLabel("Upload file:"); $form->addElement($uploadFile); $form->addElement(new Zend_Form_Element_Submit("submit")); if ($form->isValid($_POST)) { $values = $form->getValues(); $this->view->messages = array("File uploaded"); } $this->view->form = $form; } } по <?php class IndexController extends Zend_Controller_Action { ... public function fileUploadAction() { $form = new Zend_Form(); $form->setAction("/default/index/file-upload") ->setMethod("post"); $uploadFile = new Zend_Form_Element_File("uploadfile"); $uploadFile->addValidator(new Common_Validate_File_ClamAv()) ->setRequired(true) ->setLabel("Upload file:"); $form->addElement($uploadFile); $form->addElement(new Zend_Form_Element_Submit("submit")); if ($form->isValid($_POST)) { $values = $form->getValues(); $this->view->messages = array("File uploaded"); } $this->view->form = $form; } } 

Здесь вы создали простую форму и задали ее действие и свойства метода, кнопку отправки и элемент файла. Вновь созданный валидатор файла ClamAv добавляется в элемент file. Кроме того, для обязательного флага установлено значение true, обеспечивающее загрузку файла. После этого оба элемента добавляются в форму, и простой оператор if проверяет, была ли форма отправлена.

Если форма не проверяется после отправки (т. Е. Файл содержит вирус), то сообщение о проверке будет отображаться с использованием стандартного средства оформления сообщений об ошибках. В противном случае к сообщениям представления добавляется сообщение, которое будет отображаться пользователю, чтобы указать, что загрузка прошла успешно.

Последний кусок — это скрипт вида, который показан ниже:

 <h1>Zend Framework - ClamAV File Upload Validator</h1> <?php if (count($this->messages)) { echo '<ul id="messages">'; foreach ($this->messages as $message) { echo "<li>" . $this->escape($message) . "</li>"; } echo "</ul>"; } echo $this->form; 

Поскольку львиная доля работы, уже выполненной контроллером и валидатором, уже не требуется, сценарию представления не нужно делать много. Он просто отображает любые сообщения, которые были установлены контроллером, и отображает форму.

Резюме

После проработки всего этого кода у вас теперь есть новый валидатор для Zend Framework, который через библиотеку PHP ClamAv проверит, не содержит ли файл вирусов. Я надеюсь, что вы нашли эту статью полезной как для демонстрации того, как создавать свои собственные валидаторы в Zend Framework, так и для того, чтобы гарантировать, что у вас есть свободные от вирусов загрузки в приложениях, которые вы создаете, начиная с этого момента. хотел бы изучить код дальше, код для этой статьи доступен для клонирования на GitHub.

Изображение с помощью математики / Shutterstock