Перейти к содержимому
SimorghDev
← Все статьи

Как это работает · Урок 4 из 4Средний уровень · 5 мин чтения

Кто что видит: почему правила доступа должны жить в базе данных

Спрятать кнопку — не значит защитить. Попробуйте сами проникнуть в закрытую систему и посмотрите, как правила в базе данных берегут данные.

🎯 Из этого урока вы узнаете

  • чем спрятанная кнопка отличается от настоящей защиты данных
  • что такое «роли» — посетитель, участник, редактор, администратор
  • как база данных может отказать в запросе, кто бы его ни прислал
  • почему ссылки на скачивание, которые сгорают через 60 секунд, безопаснее
  • три вопроса, которые стоит задать любому разработчику, прежде чем доверить ему данные
Содержание

Представьте школу. На двери учительской висит табличка: «Только для учителей». Большинство учеников её уважают. Но дверь не заперта. Один любопытный ученик, который не обратит внимания на табличку, может войти и прочитать экзаменационные билеты.

Многие сайты защищают данные именно так: табличкой, а не замком. Этот урок показывает разницу — и даёт вам самим попробовать пройти в эту дверь.

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

Вопрос, который важен

Когда организация хранит онлайн данные участников, внутренние документы или закрытые чаты, важный вопрос — не «могут ли люди войти?». А вот какой:

Что именно каждый человек может читать и менять?

Чтобы ответить, каждому человеку дают роль:

  • Посетитель — не вошёл. Читает публичные новости, может написать через форму обратной связи.
  • Участник — вошёл. Ещё читает новости и документы для участников, пользуется чатом.
  • Редактор — ещё пишет новости и загружает документы.
  • Администратор — ещё управляет участниками и ролями, читает письма из формы обратной связи.

Пока всё хорошо. Настоящий вопрос — где живут эти правила.

Табличка на двери: правила только в приложении

Самый простой способ — положить правила в приложение. Участник не видит кнопку «Удалить». Посетитель не видит ссылку «Входящие». Выглядит безопасно.

Но приложение — лишь один из путей к данным. За каждым сайтом стоят сервер и база данных, и приложение общается с ними запросами — такими же, какие вы видели в уроке 1. Любой, кто умеет, может отправить эти запросы напрямую — без приложения, без кнопок. Часто ключ для таких запросов даже лежит внутри самой веб-страницы, потому что он нужен браузеру.

Если в самой базе нет правил, она ответит любому с этим ключом. Спрятанная кнопка была просто табличкой на незапертой двери.

Попробуйте проникнуть

Выберите, кто вы и что хотите сделать. Сначала нажмите Через приложение. Потом — Отправить запрос прямо в базу. Потом перенесите правила в базу данных и попробуйте снова.

Попробуйте

Кто что может

Где живут правила

Получилось у посетителя прочитать документ для участников, когда правила были только в приложении? Так и происходят настоящие утечки: никто не «взламывал» ничего хитрого — просто спросили базу напрямую, и она ответила.

Замок на двери: Row Level Security

База данных, которую использует Kamarob, — Postgres — умеет прикреплять правило к каждой таблице: прежде чем показать или изменить строку, проверь, кто спрашивает. Это называется Row Level Security — RLS, правила для каждой строки.

Если правило говорит «нет», база отказывает. Неважно, какой экран, скрипт или запрос спрашивает. Приложение по-прежнему прячет кнопки — это удобно людям, — но данные бережёт уже не оно.

Как выглядят правила

Вот несколько настоящих правил Kamarob, немного упрощённых. Их можно читать почти как английский текст:

-- Опубликованные публичные посты видят все; участники видят ещё и посты для участников.
create policy "posts: published for their audience" on posts for select
  using (status = 'published' and (visibility = 'public' or is_member()));

-- Писать посты могут только редакторы и администраторы.
create policy "posts: editors write" on posts for insert with check (can_edit());

-- Письма из формы обратной связи читают только администраторы.
create policy "contact: admins read" on contact_messages for select using (is_admin());

-- Человек может менять только своё имя и язык, но никогда — свою роль.
revoke update on profiles from authenticated;
grant update (full_name, locale) on profiles to authenticated;

Последние две строки стоит рассмотреть внимательнее. Даже вошедший человек, отправляя запрос напрямую, не может изменить свою роль — база просто не разрешает менять этот столбец. Роли меняются только через одну специальную функцию, которая сначала проверяет, что её вызывает администратор.

Ссылки, которые сгорают

Документы для участников — отчёты, планы, договоры — это файлы. Файлы обычно скачивают по ссылке. Но ссылку можно переслать: участник копирует её в общий чат, и теперь любой со ссылкой может скачать файл. Навсегда.

Поэтому Kamarob выдаёт подписанные ссылки, которые работают всего 60 секунд. Участник нажимает «Скачать», сервер проверяет, что он участник, создаёт свежую ссылку, и браузер сразу ею пользуется. Если кто-то перешлёт эту ссылку, к моменту, когда её откроют, она уже мертва.

Попробуйте

Ссылка, которая сгорает

Документы для участников скачиваются по ссылке, которая работает 60 секунд.

Проверяйте правила, а не только экраны

Непроверяемые правила постепенно «уплывают»: кто-то добавил таблицу и забыл её правило или поменял функцию и открыл дыру. Поэтому у Kamarob есть отдельный набор тестов, которые входят под разными людьми в настоящую базу и проверяют, что каждый может и чего не может. Например:

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

Эти тесты запускаются перед каждым выпуском. Если правило сломалось, выпуск останавливается.

Демо-администратор: показать без риска

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

Организациям, которые выбирают систему

Прежде чем доверить разработчику — или готовой платформе — данные ваших участников, задайте три вопроса:

  1. Где проверяются правила доступа? Хороший ответ: в базе данных (или на сервере), а не только в приложении.
  2. Они проверяются тестами? Хороший ответ: да, автоматически, перед каждым выпуском, под разными ролями.
  3. Что будет, если отправить запросы без приложения? Хороший ответ: ровно то же, что через приложение, — отказ там, где нельзя.

Если на первый вопрос отвечают «в приложении» — ваши данные в одном любопытном ученике от утечки.

Проверьте себя

Попробуйте

Проверьте себя

  1. 1. Участник не видит кнопку «Входящие». Защищает ли это входящие?

  2. 2. Правила только в приложении, и посетитель отправляет запрос прямо в базу. Что будет?

  3. 3. Что делает Row Level Security?

  4. 4. Почему ссылка на скачивание работает только 60 секунд?

  5. 5. Может ли вошедший участник сделать себя администратором, отправив запрос напрямую?

Маленький словарь

  • Роль — набор прав: посетитель, участник, редактор, администратор.
  • Запрос — сообщение, которое программа отправляет серверу или базе, чтобы получить данные или что-то изменить.
  • Row Level Security (RLS) — правила в базе данных, которые построчно решают, кто что может видеть и менять.
  • Политика (policy) — одно такое правило.
  • Подписанная ссылка — ссылка на скачивание, которая несёт доказательство права и быстро сгорает.
  • Демо-аккаунт — публичный вход, который может смотреть, но ничего не может менять.
  • Утечка данных — когда информация попадает к тем, кому не должна.

Берегите данные ваших участников

Я делаю платформы для организаций — новости, документы, чат, админ-панель — с правилами доступа в базе данных и тестами для каждой роли, на таджикском, русском и английском. Попробуйте демо: на главной странице kamarob.simorgh-dev.workers.dev есть вход в админ-панель только для просмотра. Вопросы: @SimorghDev.