Главная

Безопасность

Поверхность атаки браузера делится надвое: движок, который писали не мы, и оболочка, которую написали мы. Ведут они себя очень по-разному, поэтому разбираем их отдельно. Известные пробелы этого выпуска — в конце страницы.

Движок: Chromium, V8, Skia

За 2026 год в Chrome закрыли десятки уязвимостей, связанных с безопасностью памяти, в том числе шесть уязвимостей нулевого дня, которые уже использовались в реальных атаках. Этот код пишем не мы и исправить его не можем; единственная защита здесь — держать движок обновлённым.

Поэтому правило у нас простое: Girginos Browser не выпускается на версии Electron, срок поддержки которой истёк. Electron поддерживает только три последние основные версии, и закрепление версии проверяется перед каждым выпуском. Сейчас используются Electron 44.2.0 и Chromium 152.0.7977.76.

Оболочка: код, который написали мы

Вот архитектурные решения на стороне оболочки:

  • Каждая вкладка — отдельный WebContentsView. Содержимое страниц выполняется с sandbox: true, contextIsolation: true и nodeIntegration: false и не получает preload.
  • Окно интерфейса тоже работает в песочнице и использует общий сеанс со вкладками, так что и его собственные запросы проходят через блокировщик и несут заголовки DNT.
  • Каналы IPC принимаются только из главного фрейма окна интерфейса. Запись настроек проходит проверку ключа и типа.
  • Загрузки адресуются по идентификатору; необработанный путь к файлу, пришедший из интерфейса, не открывается никогда.
  • Переходы, инициированные страницей, возможны только по http(s) и view-source:http(s). file: и chrome: открываются, только если пользователь сам ввёл их в адресной строке.
  • Передача во внешнее приложение ограничена узким списком схем: mailto:, tel:, sms:, magnet:, ftp(s):, webcal:. Одновременно открыто только одно окно подтверждения.
  • Непрозрачные источники — те, у которых origin равен null, например data: и about:, — в запросах разрешений отклоняются всегда.
  • Проверка орфографии отключена, потому что Chromium скачивает файлы словарей с сервера Google.
  • Данные записываются атомарно — через временный файл и переименование.

Векторы атак и меры против них

КлассПримерМера
Подделка адресной строкиRLO/bidi, CR-LF, NUL, bank.com@evil.com, добивка пробелами, омографы IDNНевидимые символы и пробелы остаются в процентном кодировании, учётные данные скрываются, показывается punycode
Маскировка доменаaccounts.google.com.giris.evil.comРегистрируемый домен пишется насыщенным цветом, остальное — приглушённым
Подмена внутренних страницnewtab.html, скачанная копияАдрес должен совпадать целиком; поиск по подстроке не выполняется
Подделка интерфейса в полноэкранном режиместраница разворачивается на весь экран и рисует поддельную панель инструментовОбласть страницы никогда не растягивается поверх оболочки
Выход за пределы схемыfile:, chrome:, blob:, view-source:file:При переходах, инициированных страницей, — только http(s)
Вызов внешнего приложенияms-msdt:, search-ms:, ms-appinstaller:Узкий список разрешённых схем и одно окно подтверждения
Уловки с именем загружаемого файлаevil.exe / evil.exe., точка или пробел в конце, расширение, скрытое символом RLOНормализация до проверки расширения; решение принимается по настоящему имени на диске
Обход блокировщикаizleyici.com., точка в концеНормализация хоста

Подписанная цепочка обновления

Модель угроз исходит из того, что сервер обновлений уже может быть захвачен. Порядок такой:

  1. Загружаются подписанный манифест и лежащий рядом файл подписи.
  2. Подпись проверяется по сырым байтам манифеста встроенным в приложение открытым ключом Ed25519. Если проверка не проходит, не читается ни одно поле.
  3. Применяются проверки версии: откат на более раннюю версию отклоняется; манифест с истёкшим собственным сроком действия отклоняется — это защита от атаки, когда старый манифест раздаётся бесконечно, чтобы заморозить обновления; при необходимости требуется промежуточная версия; адрес загрузки обязан быть https.
  4. Версия и хеш пакета, найденные загрузчиком, должны в точности совпадать с указанными в подписанном манифесте.
  5. После загрузки хеш sha512 пакета сравнивается с подписанным за постоянное время.
  6. Установка начинается только с согласия пользователя.

Если хотя бы один шаг не проходит, обновления не будет. Закрытый ключ никогда не хранится на сервере; даже если сервер захватят, злоумышленник не сможет составить действительный манифест.

Тесты

Выполняются 118 модульных тестов, 73 регрессионных теста по векторам атак и 46 тестов проверки обновления; контракт IPC и DOM между интерфейсом и главным процессом проверяется отдельно. Кроме того, до и после выпуска запускаются сквозные проверочные скрипты — на настоящих сборках и на рабочем сервере.

Известные пробелы

Перечисленного ниже в 0.1.0 нет. Умолчать об этом значило бы показать продукт безопаснее, чем он есть, поэтому пишем прямо.

Нет Mark-of-the-Web
В скачанные файлы не записывается Zone.Identifier, поэтому Windows SmartScreen для них не срабатывает. Собственное предупреждение у браузера есть, но уровня операционной системы нет.
Нет сертификата подписи кода
Подпись кода установочного пакета проверить нельзя. Для обновлений этот вопрос закрывает подписанный манифест, но первая установка остаётся незащищённой.
Нет Public Suffix List
На хостинговых доменах вроде github.io исключения для сайта и подсветка в адресной строке охватывают больше, чем следовало бы.
Ошибки сертификата обрабатываются средствами Chromium по умолчанию
Собственный экран «всё равно продолжить» не написан; при неверном сертификате страница просто не открывается.
Блокировка только на уровне доменов
Трекеры, спрятанные за записями CNAME, и реклама, отдаваемая с первого домена, не отлавливаются; косметические фильтры не применяются.

Связанные страницы