Очистка паролей пользователей

Как я должен избегать или очищать пароли, предоставленные пользователем, прежде чем я их буду хранить и сохранить в моей базе данных?

Когда разработчики PHP рассматривают пароли пользователей хэширования для целей безопасности, они часто склонны думать о таких паролях, как о любых других предоставляемых пользователем данных. Этот вопрос часто возникает в вопросах PHP, связанных с хранением паролей; разработчик часто хочет очистить пароль, используя такие функции, как escape_string() (в разных итерациях), htmlspecialchars(), addslashes() и другие, прежде чем хэшировать его и сохранить в базе данных.

Ответ 1

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

Вы будете спорить (и вы видите это в каждом сообщении, в котором пользовательские данные принимаются для использования в ваших системах), что мы должны очищать все пользовательские данные, и вы были бы правы для любой другой части информации, которую мы принимаем от наших пользователей, Пароли разные. Хэшированные пароли не могут предложить угрозу SQL-инъекций, потому что перед хранением в базе данных строка превращается в хеш.

Актом хэширования пароля является обеспечение безопасного хранения пароля в вашей базе данных. Хэш-функция не дает особого значения для любых байтов, поэтому для обеспечения безопасности не требуется очистка его ввода.

Если вы следуете мантрам, позволяющим пользователям использовать пароли/фразы, которые они желают, и вы не ограничивать пароли, позволяя любую длину, любое количество пробелов и хэширование любых специальных символов делает пароль/парольную фразу безопасной независимо от того, что содержится в пароле. На данный момент наиболее распространенный хэш (по умолчанию), PASSWORD_BCRYPT, превращает пароль в строку шириной 60 символов, содержащую случайную соль вдоль с хешированной парольной информацией и стоимостью (алгоритмическая стоимость создания хэша):

PASSWORD_BCRYPT используется для создания новых хэшей паролей с использованием алгоритма CRYPT_BLOWFISH. Это всегда приведет к хеш файлу с использованием формата "$ 2y $" crypt, который всегда имеет ширину 60 символов.

Требования к пространству для хранения хэша могут быть изменены, поскольку к функции добавляются различные методы хеширования, поэтому всегда лучше увеличивать тип столбца для сохраненного хэша, например VARCHAR(255) или TEXT.

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

SELECT * FROM `users`;

Может быть хэширован до $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G

Посмотрите, как различные методы санировки влияют на пароль -

Пароль I'm a "dessert topping" & a <floor wax>! (В конце пароля есть 5 пробелов, которые здесь не отображаются.)

Когда мы применяем следующие методы обрезки, получаем разные дикие результаты:

var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));

Результаты:

string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>!     " // escape characters have been added
string(34) "I'm a "dessert topping" & a !     " // looks like we have something missing

Что происходит, когда мы отправляем их в password_hash()? Все они получают хеширование, как и запрос выше. Проблема возникает при попытке проверить пароль. Если мы используем один или несколько из этих методов, мы должны повторно использовать их до сравнения с password_verify(). Не удалось выполнить следующее:

password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query

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


Использование версии PHP менее 5.5? Вы можете использовать пакет совместимости password_hash() .

Вы действительно не должны использовать хэши паролей MD5.

Ответ 2

Прежде чем перевести пароль, вы должны его нормализовать, как описано в разделе раздела 4 RFC 7613. В частности:

  1. Дополнительное правило сопоставления. Любые экземпляры пространства, отличного от ASCII, ДОЛЖНЫ быть    отображается на ASCII-пространство (U + 0020); пространство без ASCII - это любой Unicode    кодовая точка, имеющая общую категорию Unicode "Zs" (с    исключение U + 0020).

и

  1. Правило нормализации: Форма нормализации Unicode C (NFC) ДОЛЖНА    применяется ко всем символам.

Это позволяет убедиться, что если пользователь вводит один и тот же пароль, но использует другой метод ввода, пароль должен быть принят.