С первого релиза Brave ведёт наиболее агрессивную из всех браузеров политику в отношении сторонних кук и других данных — мы по умолчанию делаем недоступными сторонние хранилища (и хранилище кук, и localStorage / indexedDB). Однако заход с такого козыря не только мощно повышает уровень пользовательской приватности, но и ломает массу сайтов. Рассказываем наш рецепт хранения, сортировки и выдачи кук.
Сторонним вход воспрещён
С давних времён и до наших дней отслеживание сайтами действий пользователя, по большому счёту, основано на эксплуатации одного из самых старых пороков интернета — сторонних (по-иностранному, third-party) данных: кук, записей в localStorage и т. д. Разумеется, в древние времена мало кто мог предположить, что браузерными куками будет вскормлен бессердечный спрут индустрии слежки и рекламных сетей, а конфиденциальность абонентов сети будет пожертвована во славу Больших Данных, принадлежащих Большим Корпорациям.
Как уже было сказано, простая блокировка сторонних кук — спорное решение, поскольку мешает нормальной работе множества обычных сайтов. Причём нередко ломаются важные сценарии: вход на сайт или процесс оплаты. Дело в том, что до недавних пор основные браузеры позволяли этим хранилищам работать без каких-то ограничений — соответственно и сайты не ждут подвоха или недоступности сторонних данных. Такое отсутствие ограничений позволяет всем разновидностям аналитических скриптов, следящих пикселей и рекламных сетей выдавать вашему браузеру уникальную куку и вести журнал её жизнедеятельности (в хромоподобных браузерах куки можно увидеть на странице chrome://settings/siteData)
Пример
Cайты shop.com, school.edu и bank.ru добавляют на свои страницы следящий пиксель <img src=”https://trackingcorp.com/track.gif”>. При первом запросе за этим пикселем, сайт trackingcorp.com сохранит в браузере куку с уникальным номером. При последующих запросах с сайтов магазина, школы и банка, сервер trackingcorp будет записывать историю визитов для этого номера и продавать её всем желающим за пригоршню долларов.
До недавнего времени мы балансировали между сохранением приватности и обеспечением корректности работы сайтов путём всевозможного колдунства, монтажа костылей и инжекта скриптов. Некоторые сайты приходилось просто добавлять в список исключений, иначе они отказывались работать. Это более или менее помогало оборонять наших пользователей, но стратегически это глубоко ущербный подход, который не решает проблему в целом.
Усилиями наших лучших умов (и с помощью наблюдений за другими браузерами на рынке) было придумано «эфемерное» хранилище сторонних данных — новая конструкция, которая не кормит трекеры, рекламные сети и Корпорации Добра данными пользователей, и при этом сильно реже ломает посещаемые сайты. На момент публикации мы включили эфемерное хранилище в бете и раскатываем на пользователей релизного канала.
В чем сила
Эфемерное веб-хранилище по сути представляет собой комбинацию решений по хранению данных, каждое из которых мы опишем подробнее, с оговоркой, что по результатам работы некоторые пункты могут быть пересмотрены.
Никаких кук по запросам за ресурсами (картинки, скрипты и т. д.) на сторонних доменах. Brave шлет куки по запросам на поддомены текущего сайта (например, sub.habr.com), но если это cross-origin запрос (например, за evilcorp.com/tracking_pixel.gif), ни одна кука не будет выдана.
Секционированное (то есть, раздельное) хранилище для сторонних фреймов. Скрипты, которые исполняются в таких фреймах, могут обращаться к кукам документа, localStorage или sessionStorage API (остальные API пока что, как и раньше, полностью отключены для сторонних запросов), однако фактически им будут предоставлены разные хранилища. Например, если фрейм trackingcorp.com встроен в сайты example.org и other.org, то будут созданы два хранилища: одно для trackingcorp.com + example.org, другое для trackingcorp.com + other.org. Таким образом, исключается возможность сохранения в браузере уникальной куки (или записи в localStorage) имени trackingcorp.com.
На одном и том же сайте все сущности используют одно хранилище. Например, у вас открыты две вкладки сайта first.example.org и second.example.org, на каждой вкладке есть фрейм с видео с YouTube. Оба фрейма будут обращаться к одному хранилищу. А вот если тот же YouTube-фрейм встроен в other.org или на одной из вкладок открыто то же самое видео на сайте YouTube — хранилище example.org ни тот, ни другой фрейм не увидят, ибо не положено.
Все сторонние хранилища для first-party сайта очищаются, как только закрывается последняя вкладка с этим сайтом. Соответственно, сторонние фреймы, о которых мы говорили в примерах выше, теряют данные в этих хранилищах. Пока открыта хоть одна страница для данного сайта, сторонние хранилища для фреймов существуют. Если закрыть последнюю и открыть заново — появятся новые, пустые хранилища.
После закрытия браузера очищаются все сегменты всех сторонних хранилищ. Даже при включенном восстановлении вкладок, после рестарта, хранилища будут новыми. Этот подход совпадает с алгоритмом рандомизации браузерных отпечатков в Brave, о которым мы расскажем в следующих сериях.
Пока что мы умеем только секционировать куки и localStorage, на подходе indexedDB и другие API — например, предстоит интегрироваться с Storage Access API (которое в Chromium внедряла команда Edge).
Что у других браузеров?
Пионеры секционирования сторонних хранилищ — это Safari и Tor Browser, примером которых мы и вдохновились. В отличие от Safari, Brave очищает сторонние хранилища при закрытии сайта, а не всего браузера, что существенно усиливает защиту — многие пользователи крайне редко перезапускают браузер.
Секционированное хранилище (в отличие от нас не эфемерное, а персистентное) для обороны от суперкук сделали в Firefox. Chromium же в этой области догоняющий — на сегодня в нём секционируется только кэш, и ведётся работа по другим компонентам. C 2019 года Firefox блокирует сторонние куки, принадлежащие доменам известных трекеров. А совсем недавно авторы Chromium объявили о курсе на полный запрет сторонних кук — этот процесс растянется надолго, но одной исторической ошибкой в интернете станет меньше.
nmishin
Надо будет попробовать Brave