8 октября 2013 г.

Использовать защищённый доступ к магазину через протокол SSL необходимо и важно не только с точки зрения законодательства той или иной страны (Федеральный закон РФ от 27 июля 2006 года № 152-ФЗ «О персональных данных»), но и с точки зрения собственной безопасности, когда трафик в публичных сетях постоянно прослушивается, как со стороны хакеров-любителей, так и реальных конкурентов. Особенно это актуально для точек бесплатного доступа Wi-Fi в больших городах.


В OpenCart есть соответствующая опция, отвечающая за использование протокола SSL на сайте. Разумеется сам магазин протоколом не управляет, этим занимается веб-сервер, мы всего лишь можем задать схему для ссылки (протокол HTTP или HTTPS). Опция доступна через меню панели управления (Система -> Настройки -> Магазин) в настройках магазина на закладке Сервер. Важно отметить, что "безопасный" формат ссылки не будет таковым, если не определено соответствующее значение константы HTTPS_SERVER в файле ./config.php.

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

Чтобы решить эту проблему и сохранить максимально возможную совместимость с разными видами веб-серверов (IIS, Apache, Nginx) нам потребуется написать универсальную функцию определения SSL-соединения средствами PHP:

public function is_ssl() {
if ( isset($_SERVER['HTTP_SSL']) ) {
if ( 'on' == strtolower($_SERVER['HTTP_SSL']) )
return true;
if ( '1' == $_SERVER['HTTP_SSL'] )
return true;
} elseif ( isset($_SERVER['HTTPS']) ) {
if ( 'on' == strtolower($_SERVER['HTTPS']) )
return true;
if ( '1' == $_SERVER['HTTPS'] )
return true;
} elseif ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ( 'https' == strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) ) ) {
return true;
} elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
return true;
} elseif ( isset($_SERVER['HTTP_X_FORWARDED_PORT']) && ( '443' == $_SERVER['HTTP_X_FORWARDED_PORT'] ) ) {
return true;
}
return false;
}

Эту функцию необходимо добавить в файл ./system/library/request.php. Кстати, хорошая альтернатива для замены одноименной функции в блогах WordPress. Функция учитывает как собственные переменные веб-сервера, так и переменные, передаваемые в заголовках от прокси-сервера.

Следующую функцию необходимо поместить в файл ./system/library/url.php:

public function is_https() {
return preg_match('/https:\/\//', $this->ssl);
}

Далее во всех файлах-контроллерах, где встречаются строки вида 

if ($this->customer->isLogged()) {
     ...
    $this->redirect($this->url->link('account/login', '', 'SSL'));
}

или

if ($this->affiliate->isLogged()) {
     ...
    $this->redirect($this->url->link('affiliate/login', '', 'SSL'));
}

необходимо после добавить следующий код:

elseif ($this->url->is_https() != $this->request->is_ssl()) {
    $this->redirect($this->url->link('account/*', '', 'SSL'));
}

или

elseif ($this->url->is_https() != $this->request->is_ssl()) {
    $this->redirect($this->url->link('affiliate/*', '', 'SSL'));
}

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

В Интернете есть похожие решения, но выполнены они через mod_rewrite веб-сервера Apache в файле .htaccess. Эти решения грубо говоря "прошиты" и не позволяют включать/отключать SSL через панель администрирования OpenCart.

В этой статье был затронут только защищенный протокол передачи данных, однако не стоит забывать о безопасности самого веб-сервера, в частности базы данных. Опять же, согласно Закону о персональных данных, личная информация пользователей должна храниться в зашифрованном виде, логично было бы зашифровать и информацию о заказах и финансовых транзакциях. Никто не может гарантировать, что база данных не будет использована третьими лицами без вашего согласия, например хакерами или администраторами хостинга.

Автор блога готов предложить решение по примитивной, но надёжной защите базы данных от скачивания третьими лицами. Никакого стороннего ПО или дополнительных модулей БД, всё что требуется, это возможность создавать в базе данных триггеры, процедуры и представления (view). Для виртуальных выделенных серверов такая возможность всегда есть, а для виртуального хостинга (shared hosting) может потребоваться отдельное разрешение со стороны службы поддержки.

1 комментарий:

  1. Начиная со следующего года Google будет понижать в поисковом рейтинге сайты не имеющие защищенного соединения HTTPS по умолчанию. Особенно это касается торговых площадок, т.е. магазинов.

    Кроме того, некоторые браузеры будут помечать такие сайты как небезопасные, в частности браузер Mozilla Firefox.

    ОтветитьУдалить

  • RSS
  • Twitter
  • Youtube