Приложение нормализует логины только при сохранении. Как доказать, что различия в представлении одного имени не позволяют создать дубликат учётной записи?
Нужно проверить, применяет ли система одну и ту же канонизацию логина до проверки уникальности, сохранения, аутентификации и поиска учётной записи. Для этого создают учётную запись с одним представлением имени, затем повторяют регистрацию и вход с эквивалентными Unicode-представлениями. Безопасный результат — система однозначно отклоняет дубликат или связывает все разрешённые представления с одной учётной записью, не создавая неоднозначности.
Unicode-нормализация появилась как способ привести разные последовательности кодовых точек к сопоставимому представлению. Визуально или семантически одинаковый символ может быть закодирован одним составным символом либо базовым символом с комбинируемым знаком.
Для безопасности это важно, потому что проверка уникальности, аутентификация и отображение имени могут использовать разные формы строки. Нормализация решает проблему канонически эквивалентных последовательностей, но сама по себе не устраняет все визуальные сходства между символами из разных алфавитов.
Если нормализация выполняется только после проверки или только при записи, система может принять два логина, которые затем считаются одним именем. Это создаёт неоднозначность при входе, восстановлении доступа, выдаче прав и отображении автора операции.
Опасность зависит от правил продукта. В одном случае второй пользователь может перехватить обращения, предназначенные владельцу похожего имени; в другом система будет случайно выбирать одну из двух записей. Особенно серьёзны последствия, если имя используется как ключ авторизации, идентификатор владельца ресурса или адрес для уведомлений.
Сначала нужно зафиксировать ожидаемую политику: какие формы считаются эквивалентными, допускаются ли символы разных письменностей и должна ли система запрещать смешение алфавитов. Нельзя считать любое визуальное сходство основанием для автоматического объединения: это может блокировать легитимные имена.
Затем проверяют полный жизненный цикл значения:
Практический тест включает эквивалентные Unicode-представления, различия регистра, если регистр незначим, а также запрещённые или смешанные алфавиты согласно политике продукта. Нужно проверять не только HTTP-ответ, но и состояние базы данных: после попытки регистрации не должно появляться две записи, которые система считает одним логином.
Защита должна быть многоуровневой. Нормализация на границе приложения полезна для согласованности, но уникальное ограничение в хранилище необходимо как защита от гонки между параллельными запросами. При этом в базе следует сохранять либо каноническую форму как ключ, либо отдельно хранить исходное отображаемое имя и однозначный нормализованный идентификатор.
Нормализация не заменяет экранирование, проверку длины и контроль допустимых символов. Также она не решает проблему гомоглифов — похожих символов разных алфавитов; для неё применяют отдельные ограничения, например запрет смешения письменностей или процедуру проверки имён.
В системе имя пользователя использовалось как часть пути к профилю. Регистрация проверяла уникальность исходной строки, а поиск профиля перед входом применял нормализацию. Тестировщик создал первую запись с составным Unicode-представлением символа, затем зарегистрировал визуально такое же имя в другой форме.
Вариант с исправлением только формы входа устранял ошибку авторизации, но оставлял дубликаты и неоднозначность в уже созданных данных. Исправление только базы данных было недостаточным: параллельные запросы всё ещё могли пройти предварительную проверку.
Выбранное решение включало единую нормализацию перед всеми операциями с логином, уникальный индекс по нормализованному идентификатору и миграцию конфликтующих записей с ручным разрешением владельца. Исходное имя сохранялось отдельно для отображения. После этого эквивалентное имя нельзя было зарегистрировать повторно, а вход всегда разрешал одну однозначную учётную запись.
Нет. Клиент можно обойти, а разные клиенты могут применять разные правила. Канонизация, влияющая на безопасность и уникальность, должна выполняться на доверенной стороне сервера; клиентская обработка может быть лишь удобством для пользователя.
Нет. Unicode-нормализация обычно обрабатывает канонически эквивалентные последовательности, но не доказывает, что два похожих символа обозначают одно имя. Автоматическое объединение гомоглифов может привести к ложным конфликтам, поэтому правила для смешения алфавитов и визуальных сходств задают отдельно.
Два параллельных запроса могут одновременно пройти проверку отсутствия логина, а затем оба создать запись. Уникальное ограничение на нормализованный ключ делает такое состояние невозможным независимо от порядка выполнения запросов. Приложение должно корректно обработать отказ ограничения и вернуть предсказуемый результат, не раскрывая лишние внутренние сведения.