Технический обзор для тех, кто проверяет безопасность. Всё изложенное сверяется с исходным кодом — включая то, что нас не красит: мы это называем, а не опускаем.
Бэкенда нет. Это расширение Chrome на Manifest V3, которое генерирует коды TOTP/HOTP локально с помощью OTPAuth. Мы не держим серверов, не заводим учётных записей, и у нас нет канала, по которому данные пользователя могли бы к нам попасть.
Раз нет сервера — нет и ключевого материала на стороне сервера, нет депонирования ключей и нет пути восстановления, который контролировали бы мы. Если пользователь забыл пароль и потерял код восстановления, мы не сможем помочь — так задумано.
Защита паролем необязательна и по умолчанию выключена. Когда она включена:
Данные никогда не шифруются ключом, выведенным из пароля, напрямую. Записи шифрует случайный мастер-ключ; вывод PBKDF2 только оборачивает этот мастер-ключ. Отсюда два следствия, и оба важны:
При включённой защите паролем шифруется вся запись аккаунта, кроме идентификатора и отпечатка — в том числе название сервиса, так что по украденному профилю не понять, аккаунтами каких сервисов владеет пользователь. При включении расширение шифрует записи, проверяет их расшифровкой и сравнением и только затем удаляет все копии в открытом виде: из локального хранилища браузера, из синхронизации и из всех семи ротируемых резервных снимков.
Говорим прямо, потому что для вашей оценки это существенно:
Коротко: это защищает данные в состоянии покоя. Устройство, которое уже находится под контролем атакующего во время работы, так защитить нельзя — и мы этого не обещаем.
Манифест объявляет пять разрешений и ни одного host-разрешения:
В расширении нет content-скриптов, нет разрешений tabs, cookies и webRequest и нет web-accessible-ресурсов. Ничего нашего на странице не существует, пока вы не попросите там код; то, что выполняется потом, внедряется для одной этой вкладки и одного этого вызова, по разрешению, которое даёт ваш собственный клик, и не оставляет после себя ничего.
Сканирование QR-кода камерой работает на странице расширения, открытой во вкладке, а не во всплывающем окне: popup уничтожается при потере фокуса, а запрос разрешения его как раз отбирает. Для этого не нужно разрешение в манифесте: используется штатный запрос камеры браузера, который выдаётся на origin расширения и отзывается в настройках сайта, и он никогда не появляется, пока пользователь не откроет сканер. Видео декодируется локально, никуда не передаётся и не сохраняется.
Проверка часов — единственный запрос, который расширение делает самостоятельно; всё остальное ниже происходит потому, что пользователь на это нажал. Manifest V3 запрещает удалённый код, и ничто из перечисленного не передаёт ни аккаунты, ни секретные ключи, ни сгенерированные коды. Полный список:
| Хост | Когда | Передаёт данные пользователя? |
|---|---|---|
| time.akamai.com timeapi.io cloudflare.com | Проверка расхождения часов, кэшируется; если ни один источник недоступен, об этом сказано в настройках. При сбитых часах TOTP ломается. | Нет |
| authenticator.sh | Страница приветствия при установке; страница обратной связи при удалении; страницы помощи и поддержки, когда их открывают из окна расширения. | Нет (обычные логи веб-сервера) |
| chromewebstore.google.com | Страница в магазине, открывается во вкладке только по клику: форма отзыва — из предложения оценить, наш менеджер паролей — из баннера кросс-промо. | Нет (для Google это обычный заход на страницу магазина) |
| authenticator.featurebase.app | Публичная доска пожеланий, открывается во вкладке по ссылке предложения новой функции в панели поддержки. | Только то, что пользователь там опубликует. Сторонний сервис со своими условиями. |
Ни шрифты, ни скрипты, ни стили, ни изображения не загружаются со сторонних хостов. Всё, что нужно для отрисовки интерфейса, лежит внутри пакета.
Ничего из перечисленного не нужно принимать на веру. Расширение с открытым исходным кодом, и каждый релиз воспроизводим:
.crx из Chrome Web Store и распакуйте егоnpm ci && npm run build на Node 20 LTSdist/ с распакованным пакетомSHA-256 для каждого файла в собранном dist/ публикуется с каждым релизом на GitHub в виде SHA256SUMS-v<version>.txt, в формате sha256sum — так что шаг 4 сводится к одному запуску sha256sum -c. Расхождения должны ограничиваться порядком файлов внутри архивов и пробелами в минифицированном выводе на разных патч-версиях Node.
Зависимостей в рантайме намеренно мало — OTPAuth, React, jsQR, Zustand, Framer Motion и Lucide — и все они зафиксированы закоммиченным lock-файлом. SBOM в формате CycloneDX предоставляем по запросу.
Смотреть исходный кодМы небольшой независимый разработчик. Если что-то из перечисленного для вашего процесса обязательно, лучше узнать об этом сейчас, а не на третьей неделе оценки:
Взамен мы предлагаем полную прозрачность исходного кода, проверяемую сборку, минимальный набор разрешений и отсутствие серверной инфраструктуры, которая в принципе могла бы хранить ваши данные.
Сообщения об уязвимостях и вопросы по безопасности: security@authenticator.sh. Политика раскрытия, границы применимости, сроки ответа и условия safe harbour — на странице политики безопасности; что хранится и что покидает устройство — в политике конфиденциальности.
Мы готовы заполнить письменную анкету оценки поставщика или разобрать код вместе с вашей командой безопасности.
По всему, что не касается безопасности — установка, восстановление доступа, вопросы по оплате при развёртывании — см. поддержку. Пожалуйста, не отправляйте туда сообщения об уязвимостях: этот ящик не считается конфиденциальным.