v.1.0.5-20140320
copyright (c) 2014 c61 http://c61.no-ip.org <c61@yandex.ru>
license http://opensource.org/licenses/gpl-license.php GNU Public License
Не секрет, что данные форм (в том числе пароли) отправляются на сервер незашифрованными. Поскольку использование протокола https порой невозможно или весьма затруднительно, в этом случае имеется реальная (не потенциальная) уязвимость. Пакет с данными формы можно перехватить (при определённых условиях), например, в локальной сети, при использовании открытого wi-fi, на сервере и др. Обычно это вопрос доверия провайдеру/хостеру/сисадмину.
Перспективным представляется использование асимметричного алгоритма шифрования - RSA. Его особенность - использование пары ключей: public и private. Генерируется пара ключей, в нашем случае public используется для шифрования на стороне клиента (javascript), private - для расшифровки на стороне сервера (php). Public-ключ может передаваться по открытым каналам передачи, поскольку с его помощью нельзя расшифровать им же зашифрованные данные, для этого нужен private-ключ. Подобный способ обсуждался разработчиками phpBB (см., например, http://area51.phpbb.com/phpBB/viewtopic ... 84&t=33024), но не думаю, что до версии 4 что-то будет сделано, хотя желание видеть такое в версии 3.1 было высказано. Однако, никто не мешает сделать (и использовать) такой мод.
Данный подход не гарантирует "абсолютную" защиту и неоднократно критиковался, дискуссии легко найти в сети, но достаточно весомых аргументов ни в одной из них я так и не нашёл...
Алгоритм работы мода:
- хук-функция проверяет наличие на странице форм (возможно связанных с вводом паролей) по наличию определений S_FORM_TOKEN и S_LOGIN_ACTION, а также наличие DEBUG_OUTPUT, если нет - пароли шифроваться не будут
- хук-функция генерирует пару ключей (private, public) и сохраняет их в базе данных
- хук-функция добавляет на страницы (в DEBUG_OUTPUT) код javascript, ответственный за шифрование паролей (поиск тэгов "input" типа "password" в формах, добавление "onsubmit" к подходящим тэгам "form" и функции шифрования, дополнительного тэга "input" типа "hidden" со справочной информацией); таким образом, при передаче формы на сервер вместо паролей будет передан зашифрованный текст
- при приёме запроса POST анализируется наличие зашифрованных паролей; при из наличии пароли расшифровываются и подменяются в запросе для дальнейшего использования
1) Мод добавляет на все страницы с формами код javascript, это выполняет хук hook_encrypt_passwords.php, добавляя код в DEBUG_OUTPUT. Поэтому следует убедиться в наличии DEBUG_OUTPUT в стилях и при отсутствии восстановить.
Если Вы используете мобильный стиль, то следует выполнить следующее:
В мобильных стилях не определен DEBUG_OUTPUT, используемый модом. Ршение проблемы:
- проверить, определена ли в overall_footer.html DEBUG_OUTPUT
- если нет, то добавить строку
Код: Выделить всё
<!-- IF DEBUG_OUTPUT -->{DEBUG_OUTPUT}<!-- ENDIF -->
Код: Выделить всё
<div class="copyright">
Код: Выделить всё
Powered by <a href="http://www.phpbb.com/">phpBB</a> © phpBB Group.
Код: Выделить всё
CREATE TABLE IF NOT EXISTS `phpbb_encrypt_passwords` (
`ep_id` int(11) unsigned NOT NULL auto_increment,
`time` int(11) unsigned NOT NULL default '0',
`privatekey` text collate utf8_bin NOT NULL default '',
PRIMARY KEY (`ep_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=0;
Код: Выделить всё
// Begin Encrypt Passwords Mod
define('ENCRYPT_PASSWORDS_TABLE', $table_prefix . 'encrypt_passwords');
define('ENCRYPT_PASSWORDS_SESSION_LIFE', 3600);
// End Encrypt Passwords Mod
Код: Выделить всё
// Begin Encrypt Passwords Mod
// Get form data
$ep_openssl_ext = function_exists('openssl_private_decrypt') ? true : false;
for ( $ep_index=0; $ep_index<4; $ep_index++ )
{
if ( request_var('encrypt_passwords_' . $ep_index,'') == '' ) continue;
if ( !$ep_openssl_ext && !isset($ep_id) )
{
require_once($phpbb_root_path . 'includes/encrypt_passwords/phpseclib/Crypt/RSA.' . $phpEx);
$ep_rsa = new Crypt_RSA();
$ep_rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
}
$ep_name = explode(':',$_POST['encrypt_passwords_' . $ep_index]);
$ep_idn = (int) $ep_name[0];
$ep_inputname = $ep_name[1];
$ep_b64ep = request_var($ep_inputname,'');
if ( !empty($ep_idn) && !empty($ep_b64ep) )
{
if ( !isset($ep_id) || ($ep_idn != $ep_id) )
{
$sql = 'SELECT * FROM ' . ENCRYPT_PASSWORDS_TABLE . ' WHERE ep_id = ' . $ep_idn;
$result = $db->sql_query($sql);
if ( $row = $db->sql_fetchrow($result) )
{
$ep_privatekey = $row['privatekey'];
}
$db->sql_freeresult($result);
}
if ( isset($ep_privatekey) )
{
$ep_id = $ep_idn;
$ep_ep = base64_decode($ep_b64ep);
$ep_dp = '';
if ( !$ep_openssl_ext )
{
$ep_rsa->loadKey($ep_privatekey);
$ep_dp = $ep_rsa->decrypt($ep_ep);
}
else
{
$ep_openssl_privatekey = @openssl_get_privatekey($ep_privatekey);
@openssl_private_decrypt($ep_ep,$ep_dp,$ep_openssl_privatekey);
@openssl_free_key($ep_openssl_privatekey);
}
if ( empty($ep_dp) ) $ep_dp = '';
$_POST[$ep_inputname] = $ep_dp;
$GLOBALS['_REQUEST'][$ep_inputname] = $ep_dp;
// debug...
// $mes = 'id = ' . $ep_id . '<br />inputname = ' . $ep_inputname . '<br />b64ep = ' . $ep_b64ep . '<br />dp = ' . $ep_dp . '<br />privatekey = ' . $row['privatekey'] . '<br />';
// trigger_error($mes);
}
}
}
// Delete old sessions
if ( isset($ep_id) )
{
$sql = 'DELETE FROM ' . ENCRYPT_PASSWORDS_TABLE . ' WHERE ep_id = ' . $ep_id . ' OR time < ' . (time() - ENCRYPT_PASSWORDS_SESSION_LIFE);
$db->sql_query($sql);
}
// End Encrypt Passwords Mod
- длины ключа (с уменьшением уровня безопасности, но это может потребоватся, если Вы используете маломощный сервер); найтии ЗАМЕНИТЬ 1024 на 512.
Код: Выделить всё
public $bits = 1024;
- выдачи отладочной информации (только пользователям с правами Администратора); для отключения найтии заменить значение на false
Код: Выделить всё
private $debug = true;
Отладочная информация выдаётся при включенной в config.php опции DEBUG внизу экрана (строка с всплывающей подсказкой с именем мода и номером версии) в форматегде Time - время выполнения хук-фунции.Код: Выделить всё
hEP Time : 0.000s
...
ВНИМАНИЕ !!! Из-за специфики hook system phpBB стандартная отладочная информация выдаётся без учёта времени выполнения хук-функций и количества выполненных в них sql-запросов
...
Код: Выделить всё
includes/encrypt_passwords/phpseclib/openssl.cnf
includes/encrypt_passwords/phpseclib/Crypt/RSA.php
includes/encrypt_passwords/phpseclib/Crypt/Hash.php
includes/encrypt_passwords/phpseclib/Crypt/Random.php
includes/encrypt_passwords/phpseclib/Crypt/Math/BigInteger.php
includes/hooks/hook_encrypt_passwords.php
styles/jsencrypt.min.js
Примечания
1) Поскольку передаваемый пароль подменяется на зашифрованный, функция браузера "запомнить пароль" может не работать, если используется устаревший браузер. В современные браузерах проблем не возникает.
2) Для создания ключей на стороне сервера используется phpseclib. Для шифрования на стороне клиента используется jsencrypt. Для расшифровки на стороне сервера используется расширение php openssl или, если оно не установлено, phpseclib (в этом случае дешифрование идёт не очень быстро, на слабом сервере может исчисляться единицами секунд, так, у меня тестовая площадка собрана на маршрутизаторе и дешифрование занимает около 5 секунд при загрузке процессора 25%).
ВНИМАНИЕ !!! Алоритм шифрования в текущей версии не претендует на абсолютное совершенство. Поскольку отладка проводилась на слабом сервере, некоторое дополнительные меры по обеспечению безопасности не были применены. Желающие могут дополнить мод...
Спасибо Shredder'у за тестирование и оформление мода в формате MODX ! Спасибо maco8024 за тестирование ! Скачать MODX можно здесь
Тема на моей тестовой площадке тынц
Скачать: Скачать предыдущие версии: