Безопасность
Поверхность атаки браузера делится надвое: движок, который писали не мы, и оболочка, которую написали мы. Ведут они себя очень по-разному, поэтому разбираем их отдельно. Известные пробелы этого выпуска — в конце страницы.
Движок: 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., точка в конце | Нормализация хоста |
Подписанная цепочка обновления
Модель угроз исходит из того, что сервер обновлений уже может быть захвачен. Порядок такой:
- Загружаются подписанный манифест и лежащий рядом файл подписи.
- Подпись проверяется по сырым байтам манифеста встроенным в приложение открытым ключом Ed25519. Если проверка не проходит, не читается ни одно поле.
- Применяются проверки версии: откат на более раннюю версию отклоняется; манифест с истёкшим собственным сроком действия отклоняется — это защита от атаки, когда старый манифест раздаётся бесконечно, чтобы заморозить обновления; при необходимости требуется промежуточная версия; адрес загрузки обязан быть https.
- Версия и хеш пакета, найденные загрузчиком, должны в точности совпадать с указанными в подписанном манифесте.
- После загрузки хеш sha512 пакета сравнивается с подписанным за постоянное время.
- Установка начинается только с согласия пользователя.
Если хотя бы один шаг не проходит, обновления не будет. Закрытый ключ никогда не хранится на сервере; даже если сервер захватят, злоумышленник не сможет составить действительный манифест.
Тесты
Выполняются 118 модульных тестов, 73 регрессионных теста по векторам атак и 46 тестов проверки обновления; контракт IPC и DOM между интерфейсом и главным процессом проверяется отдельно. Кроме того, до и после выпуска запускаются сквозные проверочные скрипты — на настоящих сборках и на рабочем сервере.
Известные пробелы
Перечисленного ниже в 0.1.0 нет. Умолчать об этом значило бы показать продукт безопаснее, чем он есть, поэтому пишем прямо.
- Нет Mark-of-the-Web
- В скачанные файлы не записывается Zone.Identifier, поэтому Windows SmartScreen для них не срабатывает. Собственное предупреждение у браузера есть, но уровня операционной системы нет.
- Нет сертификата подписи кода
- Подпись кода установочного пакета проверить нельзя. Для обновлений этот вопрос закрывает подписанный манифест, но первая установка остаётся незащищённой.
- Нет Public Suffix List
- На хостинговых доменах вроде github.io исключения для сайта и подсветка в адресной строке охватывают больше, чем следовало бы.
- Ошибки сертификата обрабатываются средствами Chromium по умолчанию
- Собственный экран «всё равно продолжить» не написан; при неверном сертификате страница просто не открывается.
- Блокировка только на уровне доменов
- Трекеры, спрятанные за записями CNAME, и реклама, отдаваемая с первого домена, не отлавливаются; косметические фильтры не применяются.