Веб по-прежнему просит пользователей доверять коду, который только что пришёл с сервера#
Пост Mozilla Hacks под названием «Trustworthy JavaScript for the Open Web» указывает на слабое место современной модели доверия в вебе: браузеры выполняют код, который сервер отдаёт в момент запроса, даже если этот код работает с чувствительными данными.
Именно эта модель сделала веб мощным. Но она же сделала доверие скользким.
Пользователь может открыть веб-приложение для личной переписки, банкинга, медицинских записей, рабочих документов или сценариев идентификации. Браузер изолирует страницу от остальной системы и поддерживает границы безопасности. Но сам код приложения обычно приходит с сервера, которым управляет поставщик сервиса, CDN или другой участник цепочки доставки.
При обычной работе браузер доверяет полученному JavaScript и ресурсам: предполагает, что это правильные файлы. Если завтра сервер пришлёт другой код, браузер, как правило, выполнит и его. Именно на этот стык обращает внимание Mozilla.
Что точно следует из источника#
В приведённом фрагменте есть три конкретных тезиса.
Во-первых, открытый веб теперь используют для приложений, которые обрабатывают чувствительные данные. Среди примеров названы личные коммуникации, финансовые операции и медицинские записи.
Во-вторых, традиционная веб-модель полагается на то, что серверы доставляют браузерам правильный код и ресурсы. Браузер затем даёт этому коду защищённую и изолированную среду выполнения.
В-третьих, Mozilla описывает это серверное допущение доверия как недостаточное «в некоторых обстоятельствах». В фрагменте нет полного технического предложения, модели развёртывания, описания поведения браузера, threat model или статуса реализации. Эти детали стоит читать в оригинальном посте Mozilla Hacks, прежде чем делать выводы о том, что именно Mozilla предлагает или уже поставляет.
Эта неопределённость важна. «Trustworthy JavaScript» может относиться к нескольким соседним задачам: проверке того, что код совпадает с опубликованным исходным кодом, защите от тихой подмены кода, большей прозрачности сборок, усилению supply chain или более сильным гарантиям для пользователя о том, что выполняет его браузер. Фрагмент обозначает область проблемы. Сам по себе он не доказывает, какой механизм Mozilla подробно поддерживает.
Почему это важно#
Песочница браузера — не то же самое, что целостность приложения.
Браузер может не дать одному origin читать данные другого origin. Он может ограничить доступ к локальным файлам, устройствам и привилегированным системным API. Он может применять HTTPS, content security policy, same-origin rules и другие механизмы.
Но если собственный сервер приложения отдаёт вредоносный или изменённый JavaScript, эти защиты могут не ответить на главный вопрос: тот ли это код, который пользователь ожидал запустить?
Это особенно важно для сервисов со сквозным шифрованием и других чувствительных веб-приложений. Если мессенджер работает в браузере, шифрование может выполняться локально. Но JavaScript, который шифрует данные, обычно приходит от сервиса каждый раз при загрузке или обновлении приложения. Скомпрометированный сервер, давление на провайдера, отравленный deployment pipeline или вредоносное обновление могут изменить то, что получит браузер.
Та же проблема есть и за пределами мессенджеров. Финансовое приложение может показывать привычный доверенный интерфейс, но выполнять изменённую клиентскую логику. Медицинский портал может раскрыть чувствительные записи через код, который пользователь не может легко проверить во время выполнения. Сервис идентификации может изменить страницу, где проходят аутентификация или восстановление доступа.
Это не утверждение, что веб-приложения небезопасны по умолчанию. Речь о другом: обычная модель доставки в вебе требует большого доверия к стороне, которая отдаёт код.
Где проходит настоящая граница доверия#
Для многих пользователей HTTPS выглядит как граница доверия. Значок замка говорит, что соединение зашифровано, а личность сайта в некоторой степени проверена. Это полезно. Так множество сетевых атакующих не могут переписать трафик по пути.
Но HTTPS не сообщает пользователю, отдал ли сервер тот же JavaScript, который проверяли аудиторы. Он не доказывает, что production bundle собран из публичного репозитория исходного кода. Он не доказывает, что CDN, зависимость, deployment key или build system не были скомпрометированы до того, как код попал в браузер.
Именно этот пробел стоит за многими разговорами о доверенном коде в вебе. Открытый веб даёт пользователям доступность и переносимость. Но он также даёт операторам приложений постоянный контроль над путём кода.
Такой контроль удобен. Ошибки можно быстро исправлять. Патчи безопасности доходят до пользователей без задержек app store. Новые функции можно выкатывать без просьбы установить новый бинарный файл.
Цена в том, что у пользователей и исследователей часто мало гарантий о том, какой код выполнялся в конкретной сессии.
Чего не стоит утверждать сверх источника#
Фрагмент не доказывает, что Mozilla решила всю проблему. В нём не сказано, что текущие браузеры вот-вот начнут отклонять непроверенный JavaScript. Он не содержит свидетельств новой кампании эксплуатации. В нём нет названия уязвимости, CVE или конкретного затронутого продукта.
Это также не значит, что нативные приложения автоматически лучше. У них свои проблемы supply chain, обновлений, подписи, магазинов приложений, телеметрии и воспроизводимости сборок. Подписанное приложение всё равно может быть вредоносным. Публичный репозиторий не доказывает, что распространяемый бинарный файл собран именно из этих исходников. Проверка в app store не доказывает, что поведение во время выполнения безопасно.
Полезный вывод уже: у веб-приложений есть своя устойчивая проблема целостности, потому что исполняемый код часто загружается с сервиса в момент открытия.
Эта проблема становится острее, когда приложение просит доверить ему секреты.
Что проверить дальше#
Для пользователей практический вывод такой: отделяйте доверие к транспорту от доверия к коду. HTTPS нужен, но для приложений с высокой чувствительностью это не полный ответ. Выбирая инструменты для личной переписки, финансов, здоровья или идентификации, ищите понятные заявления о threat model проекта, целостности клиента, истории аудитов, пути обновлений и воспроизводимых сборках там, где это уместно.
Для разработчиков первый вопрос — где задокументированы допущения доверия вашего приложения. Если ваша модель безопасности опирается на клиентский JavaScript, который защищает секреты пользователя, объясните, как пользователи или аудиторы могут убедиться, что развёрнутый код совпадает с проверенным. Если ответ звучит как «они доверяют нашему серверу», это может быть честно. Но для некоторых сценариев этого может быть мало.
Для security-команд это хороший чек-лист для ревью:
- Какой код может измениться без видимости для пользователя?
- Кто может выкатывать production JavaScript?
- Какие сторонние скрипты могут влиять на чувствительные сценарии?
- Сборки воспроизводимы или хотя бы трассируемы?
- Может ли пользователь, аудитор или браузер проверить, что именно было доставлено?
- Что произойдёт, если deployment pipeline будет скомпрометирован?
Это не абстрактные вопросы. Они определяют, кто может незаметно изменить приложение, которое пользователь считает запущенным.
Главное#
Пост Mozilla стоит прочитать, потому что он говорит о тихой, но центральной проблеме: открытый веб зависит от кода, который доставляют just in time стороны, не всегда проверяемые пользователем.
Эта модель никуда не исчезнет. Она слишком полезна. Но для чувствительных приложений «браузер запустил это в песочнице» не равно «пользователь может доверять тому, что выполнилось».
Следующий серьёзный шаг для веба — не только более сильная изоляция. Нужны лучшие доказательства о самом коде.