Я сказал бы лень. Массивы запускаются в 0 (все знают это); месяцы года являются массивом, который приводит меня полагать, что некоторый инженер в Sun просто не потрудился помещать эту небольшую точность в код Java.
Мысли:
Используйте истинный асимметричный шифр для «cookie», чтобы предотвратить создание учетных записей ботами. Зашифруйте «cookie» с помощью открытого ключа, проверьте его путем декодирования с помощью закрытого ключа.
Обоснование: Если бы для кодирования cookie использовался только алгоритм base64 или другой алгоритм, было бы легко перепроектировать схему и создавать учетные записи автоматически. Это нежелательно из-за спам-ботов. Кроме того, если учетная запись защищена паролем, пароль должен появиться в файле cookie. Любой, у кого есть доступ к ссылке для регистрации, сможет не только активировать учетную запись, но и узнать пароль.
Требовать повторного ввода пароля после активации по ссылке.
Обоснование: В зависимости от цели сайта вам может потребоваться улучшить защиту от подделки информации. Повторный ввод пароля после активации защищает от кражи / подделки ссылок активации.
При проверке ссылки активации убедитесь, что созданная им учетная запись еще не создана.
Как вы защитите себя от одновременного создания учетной записи двумя пользователями с тем же именем?
Возможный ответ: Использовать электронную почту в качестве идентификатора входа и не требовать уникального имени учетной записи.
Сначала проверьте адрес электронной почты, а затем продолжите создание учетной записи.
Обоснование: Это сведет к минимуму информацию, которую вам необходимо отправить в куки.
Есть некоторые почтовые клиенты, которые прерывают URL-адреса после 80 букв. Я сомневаюсь, что вы сможете уместить в них всю информацию.
Некоторые браузеры имеют ограничения для URL-адресов, например Internet Explorer 8 имеет ограничение в 2083 символа.
Почему бы вам не чистить базу данных регулярно (скрипт cron) и не удалять все учетные записи, которые еще не активирован на 24 часа?
Я делал почти то же самое раньше. У меня есть только 2 предложения для вас:
Что касается самого короткого URL, вы можете улучшить его, внеся следующие изменения:
Base64.urlsafe_encode64 ()
, чтобы вам не приходилось его кодировать по URL. Есть несколько проблем с вашим решением.
Во-первых, вы не устанавливаете IV шифра. На мой взгляд, это выявило серьезную ошибку в оболочке Ruby OpenSSL - она не должна позволять выполнять шифрование или дешифрование, пока не будут установлены оба ключа
и iv
, но вместо этого идти вперед и использовать IV из нулей. Использование одного и того же IV каждый раз в основном устраняет большую часть преимуществ использования режима обратной связи.
Во-вторых, что более серьезно, у вас нет проверки подлинности. Одно из свойств режима CBC заключается в том, что злоумышленник, имеющий доступ к одному сообщению, может изменить его, чтобы создать второе сообщение, в котором блок во втором сообщении имеет полностью контролируемое злоумышленником содержимое за счет полного искажения предыдущего блока. (Ой, и обратите внимание, что режим CFB является такой же проблемой в этом отношении).
В данном случае это означает, что я могу запросить учетную запись с Фамилией AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA и своим собственным адресом электронной почты, чтобы получить действительный URL. Затем я могу , не зная ключа , изменить адрес электронной почты на Victim@victim.com
(и искажать фамилию в процессе, что не имеет значения) и иметь действующий URL-адрес, который я могу отправить на ваш сервер и создать учетные записи для адресов электронной почты, которые я не контролирую.
Чтобы решить эту проблему, вам необходимо вычислить HMAC для данных, используя секретный ключ, известный только серверу, и отправить его как часть URL-адреса. Обратите внимание, что единственная причина, по которой вам вообще нужно шифрование, - это защита пароля пользователя - кроме того, что это может быть просто текст и HMAC. Я предлагаю вам просто отправить в качестве URL-адреса что-то вроде:
?ln=Last%20Name&fn=First%20Name&email=foo@bar.com&hmac=7fpsQba2GMepELxilVUEfwl3%2BN1MdCsg%2FZ59dDd63QE%3D
... и попросить страницу подтверждения ввести пароль (похоже, нет причин возвращать пароль туда и обратно).
Я постараюсь описать проект, который может работать.
Предварительные требования:
Дизайн:
Процесс:
cookie = ENCRYPT (CONCAT (электронная почта, '.', H (пароль)), открытый ключ)
http://example.org/activation?cookie= [cookie]
http://example.org/activation
расшифровывает cookie, переданный как параметр: data = SPLIT (DECRYPT (cookie, закрытый ключ), '.')
Укажите все, что я пропустил, или какие-либо улучшения. Я был бы рад соответствующим образом обновить ответ.