Очищення паролів користувача


98

Як я повинен уникнути або очистити надані користувачем паролі, перш ніж їх хешувати і зберігати їх у своїй базі даних?

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


1
Ви можете користувач base64 кодувати
MSS

Ні @MSS, ви не повинні, тому що base64 кодує , а не шифрує чи хеширує . Паролі завжди повинні бути хешованими .
Джей Бланшард

1
Я маю на увазі перед хеш;)
MSS

Вам не слід і не потрібно цього робити перед хешированием. Це призведе до того, що вам доведеться писати непотрібний додатковий код @MSS
Jay Blanchard

Відповіді:


99

Ніколи не слід уникати, обрізати чи використовувати будь-який інший механізм очищення паролів, які ви стикаєте з PHP з password_hash()ряду причин, одна з найбільших з яких полягає в тому, що для додаткового очищення пароля потрібен зайвий додатковий код.

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

Акт хешування пароля - це зробити безпечний пароль для зберігання у вашій базі даних. Хеш-функція не надає особливого значення жодним байтам, тому очищення його вводу не потрібно з міркувань безпеки

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

PASSWORD_BCRYPT використовується для створення нових хешей паролів за допомогою алгоритму CRYPT_BLOWFISH. Це завжди призведе до хешу з використанням криптовалютного формату "$ 2y $", який завжди має ширину 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 .


13
Ні. Якщо він створив свій пароль із пробілами, які дозволено, він повинен використовувати їх під час входу @DanBracuk
Jay Blanchard

12
Як так @DanBracuk? Якщо ми дозволимо користувачеві встановити потрібний пароль, включаючи провідні / пробіли?
Джей Бланшард

16
Ось чому більшість речей вимагає, щоб ви ввели вибраний пароль двічі. Якщо користувач додав пробіли випадково, він розбереться перед тим, як отримати далі. Якщо користувач зробив це навмисно, то це не проблема.
Я боровся ведмедя одного разу.

4
@MargaretBloom, правило є просто евристичним. Нам іноді ще потрібно все продумати, як, наприклад, паролі. Ви говорите: "ніхто не знає, як зміниться ситуація в майбутньому", але, здається, якщо щось зміниться - це те, як ми уникнемо дані, перш ніж вносити їх у базу даних; у цьому випадку користувачі виявляться заблокованими, коли їх паролі ні довше відповідають тому, що ми зберегли. Яка небезпека не уникнути хешей паролів порівняно з небезпекою їх уникнення?
DavidS

3
Точно так: ви, звичайно, "уникнете хешу" в обмеженому розумінні, щоб правильно передати його параметризованому SQL-запиту, де якийсь код у вашому SQL-роз'ємі може чи не робити нічого з цим, що відповідає "втечі", ви не робите " не знаю і не байдуже. Вам просто не доведеться писати якийсь конкретний код, щоб досягти цього, тому що це повністю рутина для всіх ваших SQL запитів, якщо ви раніше не приймали якісь життєві рішення.
Стів Джессоп

36

Перш ніж хешувати пароль, слід нормалізувати його, як описано в розділі 4 RFC 7613 . Зокрема:

  1. Додаткове правило картографування: Будь-які екземпляри простору, що не належить до ASCII, ОБОВ'ЯЗКОВО бути відображено в простір ASCII (U + 0020); простір без ASCII - це будь-яка точка коду Unicode, що має загальну категорію Unicode "Zs" (за винятком U + 0020).

і:

  1. Правило нормалізації: Форма нормизації Unicode C (NFC) ОБОВ'ЯЗКОВО застосовується до всіх символів.

Це намагається переконатися, що якщо користувач вводить один і той же пароль, але використовуючи інший метод введення, пароль все одно слід прийняти.


3
@DavidS, Супер блискуча північноамериканська книга Mac (яку Джо використовував безпосередньо перед від'їздом) та погано інтернаціоналізований тайваньський комп'ютер з Інтернет-кафе (який Джо намагається використати для завантаження - бортова картка назад.
Маргарет Блум

2
Звучить дзвінко. :-) Хоча спасибі.
DavidS

3
Хм. Якщо ви це зробите, то вам також слід підтвердити паролі, щоб відхилити будь-які символи, які ще є непризначеними. Було б жахливо, якщо користувач використовує NEWFANGLED SPACE, який ваш додаток не розпізнає, а тому хеширує його як є, а потім ви оновите базу даних символів Unicode і раптом NEWFANGLED SPACE буде відображено до SPACE перед хешированием, так що він (и) він більше не можна вводити пароль, який ваш додаток хеш до старого хешу.
ruakh

4
@JayBlanchard Тому що, коли ви натискаєте пробіл на одній машині і коли ви натискаєте його на іншій машині, у вас можуть з’явитися дві різні кодові точки Unicode, і вони матимуть два різних кодування UTF-8, без того, щоб користувач нічого не знав. Можна стверджувати, що це проблема, яку ви хочете ігнорувати, але RFC 7613 виникла з таких проблем у реальному житті, це не рекомендація щодо виконання робіт.
Поновіть Моніку

1
@ruakh Після того, як ви вирішите обробляти паролі певним чином, вони повинні залишатися таким чином, інакше все порушиться для існуючих випадків використання. Якщо ви плануєте змінити метод попередньої обробки в майбутньому, вам слід зберегти його вздовж попередньо обробленого та хешованого подання пароля. Таким чином, щойно ви отримуєте вхід, ви вибираєте метод попередньої обробки / хешування на основі того, з чим ви порівнюєте.
Відновіть Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.