Серверний фінгерпринтинг: 4 режими приватності
Вхід із нового пристрою це або клієнт у потязі, або вкрадений пароль, і рядок у лозі, який розрізнив би ці випадки, в обох однаковий. Серверний фінгерпринтинг збирає ідентифікатор із того, що запит уже несе, і питання в тому, скільки з цього ви готові зберігати.
Код: Fingerprint-PHP, ліцензія MIT.
composer require globus-studio/fingerprint, PHP 8.3 і новіше, чотири режими приватності й робота з довіреними проксі, яка відмовляється вгадувати.
Навіщо це потрібно
Три місця окупають витрати. Вхід із незнайомого пристрою може попросити другий фактор замість того, щоб прийняти пароль. Оформлення замовлення з адреси, якої раніше не було, іде на ручну перевірку замість відмови. Наявна сесія, що раптом змінила пристрій, потрапляє в журнал, і так знаходять зламаний акаунт до повернення грошей.
Жодному з цих випадків не потрібна впевненість. Кожному потрібен сигнал, достатній для зайвого кроку, і це фінгерпринт дати може.
Чотири режими
strict збирає мінімум сигналів і не зберігає повний IP та сирі значення. balanced це рекомендоване типове значення для безпеки. maximum піднімає кількість сигналів і вимагає сильнішої правової підстави. custom дає застосунку змогу назвати свою політику.
Починати з balanced і переходити до maximum лише із записаною причиною це послідовність, яку приймає перевірка приватності. Починати з maximum і обіцяти знизити пізніше це послідовність, яку ніхто не закінчує.
Проксі це місце, де зазвичай ламається
За CDN або балансувальником усі запити виглядають такими, що прийшли з однієї адреси. Лікується списком довірених проксі, а не сліпим читанням заголовків: withTrustedProxies(['10.0.0.0/8']) і withTrustedHeaders(['x-forwarded-for']), причому заголовки ігноруються, доки REMOTE_ADDR не в списку.
Це правило закриває просту атаку, де клієнт сам ставить X-Forwarded-For і обирає собі відбиток. Воно ж перше, що перевіряють після переїзду: хибний список проксі дає один ідентифікатор на всіх відвідувачів і алерт, схожий на DDoS.
Збіг це рівень, а не так чи ні
compare() повертає рівень збігу, а level()->isSuspicious() це питання, яке ставить форма входу. Два відбитки ніколи не збігаються повністю, бо версія браузера й розмір екрана змінюються.
Логічне «той самий пристрій» змушує обрати поріг, який неможливо захистити на рев’ю. Рівень дає застосунку змогу сказати, що воно робить із середнім збігом, і зазвичай це прохання про другий фактор.
Чого це не може
Фінгерпринтинг імовірнісний. NAT, VPN, корпоративні проксі, мобільні мережі, налаштування приватності й оновлення браузерів змінюють сигнали, а людина, яка перемикається між Wi-Fi і мобільним інтернетом, виглядає як два пристрої.
README прямо пише, що відбиток не може бути єдиним фактором автентифікації або блокування. Команда, яка прочитала цей рядок, будує другий фактор; команда, яка пропустила, замикає клієнтів у відпустці.
Що перевірити першого дня
Логуйте ідентифікатор тиждень до того, як щось обмежувати. Перша знахідка зазвичай у хибному налаштуванні проксі, друга в тому, що мобільні користувачі дають два-три ідентифікатори за день.
Ні те, ні те не привід відмовлятися від підходу; обидва привід спершу попрацювати в режимі звіту.
Окремо варто перевірити, що відбувається під час зміни версії алгоритму. Якщо набір сигналів змінюється, збережені відбитки перестають збігатися, і про це краще знати з документа, а не з логів.
Рахунок за приватність
Відбиток це персональні або псевдонімізовані дані. Йому потрібні правова підстава, політика зберігання й перевірка приватності, і режим це частина рішення, а не налаштування для розробника.
Там, де рішення записане, бібліотека лишається інструментом. Там, де ні, та сама бібліотека стає зобов’язанням із журналом змін.
Поруч: розробка на PHP про те, як рахується така інтеграція, і розробка плагінів WordPress про контекст, у якому серверні перевірки зазвичай живуть.
