xenon
@xenon
Too drunk to fsck

Есть ли базы данных, хранилища, бэкенды для конфиденциальных данных?

С веб-приложениями есть проблема в том, что в случае уязвимости в нем, сразу можно потерять практически все данные, к которым имеет доступ приложение, а средства безопасности SQL не позволяют надежно и тонко настроить права доступа.

Например, если в приложении есть SQL Injection, то найдя ее, взломщик просто отдает запрос SELECT * FROM customers; и получает список всех клиентов с паролями. Он может это сделать, потому что язык SQL дает такую возможность. Хотя с точки зрения безопасности, фронтенду именно такая опасная операция никогда не нужна (но нужен доступ к табл. customers).

Поэтому есть идея: а что если разделить данные и хранить по разному? 99% данных (они и так публичны или не слишком дороги, например, список товаров, описания, картинки, цены) - будут в обычной СУБД. Существующее приложение на 99% не изменится. Но 1% мы выносим куда-то на.... (тут не знаю, как назвать это, ну давайте назовем secure backend) и работаем с ним по API, которое, в отличие от SQL заточено на безопасность. В результате, что мы имеем:
1. Даже полный доступ к базе не дает доступа к secure backend
2. Даже root доступ к серверу, все равно не открывает возможность все слить с secure backend!

Примеры, как он мог бы работать:
Логин
При логине, есть возможность проверить, что username/password соответствует. (Но нельзя получить даже хеш пароля). Опционально - может быть даже ratelimit на эти операции, чтобы нельзя было bruteforce. Например, передается IP клиента, и более 10 запросов в минуту вызывают блокировку.

После логина, открываются возможности чтения профиля клиента. Например, адрес доставки, история покупок, итд. Как вариант, эта история и так хранится в SQL, но не имея какого-то id клиента, невозможно их увязать не выполнив успешную процедуру логина. Взломщик может узнать, что 21 числа была куплена тумбочка, но купил ее secure:user:id:123, а кто это - не знает.

Не-SQLные ограничения
Оператор в отделении банка в среднем обслуживает 20 человек в день (допустим), мы выделяем ему лимит, он может запросить данные о 50 клиентах банка из этого города, и 5 из других городов (чтобы избежать ситуации "где карту получали, туда и обращайтесь). Это не мешает ему в обычной работе, но он в принципе не может слить всю базу всех клиентов банка. (Через SQL, веб приложение с уязвимостью - может)

Разные роли пользователей
Веб-приложение устанавливает коннект к API именно как веб-приложение и имеет свой "профиль" (правила доступа). Например, оно в принципе не может получить список всех клиентов, никогда. Админка - может. Но чтобы приложение "залогинилось" как админка - во-первых, нужно код приложения изменить (т.е. получить root на фронтенд-сервере), а во-вторых, пройти доп. ограничения, например, знать пароль админа, а он никогда не вводится на фронтенде, или же вообще, админ может работать только с других IP адресов.

Есть ли уже готовые похожие решения для чего-то подобного?
  • Вопрос задан
  • 659 просмотров
Пригласить эксперта
Ответы на вопрос 8
@vitaly_il1
DevOps Consulting
Посмотрите на WAF, особенно на Database Firewalls (https://www.imperva.com/ и т.п.)
Есть советы по безопасной архитектуре от OWASP,
по прохождения аудита на PCI, SOC2.
Ответ написан
@nApoBo3
Это можно реализовать тонко настроив ограничения, плюс хранимые процедуры и триггеры. Но обычно так не делают поскольку это значительно усложняет систему и может крайне негативно сказаться на производительность ( а там где важна такая безопасность обычно важна и производительность ).
Ответ написан
profesor08
@profesor08
взломщик просто отдает запрос SELECT * FROM customers; и получает список всех клиентов с паролями

Ничего не получает, хоть запрос и выполнится, а если твой код не обрабатывает подобный кейс, то будет ошибка. Но он может сделать DROP TABLE customers, или сразу всю бд дропнуть.

Если злоумышленник получит доступ, то ему не составит труда обратиться и по api куда надо.
Ответ написан
Хм, ну ещё ко всем ответам, могу предложить Hashicorp Vault
Ответ написан
@Vitsliputsli
Посмотрите в сторону мандатного контроля, это в первую очередь решения на основе SELinux, и основные СУБД их поддерживают.
Ответ написан
@zavodp
Например, если в приложении есть SQL Injection, то найдя ее, взломщик просто отдает запрос SELECT * FROM customers; и получает список всех клиентов с паролями. Он может это сделать, потому что язык SQL дает такую возможность. Хотя с точки зрения безопасности, фронтенду именно такая опасная операция никогда не нужна (но нужен доступ к табл. customers).

Есть куча решений:

1) СУБД дает такую возможность. Но совсем не обязательно, чтобы у пользователя SQL, используемого фронтендом был доступ к таблице customers, где хранятся пароли. К другим таблицам - пожалуйста. К этой - нет. Проверка паролей - только через отдельный сервер типа oAuth.

2) В СУБД есть куча тонких настроек ограничений доступа, даже если вам нужно дать доступ к таблице customers, где хранятся пароли.
https://www.postgresql.org/docs/10/ddl-rowsecurity.html
https://docs.microsoft.com/en-us/sql/relational-da...

3) Пароли хранить не нужно. Достаточно хранить "подсоленый хэш". Получение соленых хешей ничего не даст.
https://habr.com/en/post/145648/
https://habr.com/en/post/210760/
https://habr.com/en/post/145667/
https://habr.com/en/post/39079/

4) Есть специализированные БД, для хранения секретов.
Они, в отличие от обычных СУБД. невкрываемы, даже если злоумышленник утащит все файлы СУБД.
Также они позволяют вести аудит.
Также позволяют организовывать отзыв паролей и т.п.
Полностью задачу решить, понятно, нельзя, так как если злоумышленник проникнет внутрь и получит токен для доступа к данным, то до самих данных он доберется и тут.
Но хотя бы этот доступ будет ограниченным во времени.
https://habr.com/en/company/oleg-bunin/blog/438740/
https://habr.com/en/post/306812/

5) Можно вообще не хранить пароли в обычном виде в СУБД, а передавать их в приложение при старте через переменные среды окружение.
И пр.
И т.п.

6) Ограничение простого перебора. Исключить использование идентификаторов вида 1, 2, 3, 4, 5. А использовать что то вроде 0xF6C0F6C5430DC8904F60ABE822345200 и добавить throttling, чтобы ограничить скорость перебора. Уже не говоря о жесткой блокировке по IP при слишком большом количестве попыток перебора.

7) А с чего это ему хоть что то отдастся при таком запросе?
взломщик просто отдает запрос SELECT * FROM customers; и получает список всех клиентов с паролями

А зачем ваш бэкенд вообще по чьей либо указке выполняет непредусмотренный запрос? У меня вон в коде и предусмотренные запросы не так просто заставить выполнить. Выполняются только в строгих рамках разрешенного и предусмотренного при разработке.

SQL Injection вообще невозможен при современном подходе, кода выполняется только то, что предусмотрено; когда используются современные фреймворки и современные библиотеки, где всё фильтруется на несколько раз.
Ваш пример - это что-то из 2000-2010-х годов. Давно уже подобный код, разрешающий всё не практикуется.
Хотя, программисты конечно разные бывают....

Короче, методов защиты очень и очень много.

Тут дело вовсе не в специальной СУБД.
Так как и к ней можно получить доступ.

Дело в принципе - разделяй и властвуй.
Чтобы даже где-то что то получив, злоумышленник не смог сделать много вредного.
Ответ написан
Комментировать
samodum
@samodum
Какой вопрос - такой и ответ
зломщик просто отдает запрос SELECT * FROM customers; и получает список всех клиентов с паролями

В нормальной базе он получит не пароли, а бесполезные для него хэши
Ответ написан
@tester12
Это решается дополнительным слоем, реализующим "внешний" API.

Клиентское приложение вместо
select value from mytable where id=5
запрашивает
https://myhost.com/get.php?id=5

А уже скрипт решает, выдавать данные юзеру или нет, уложился он в лимиты или нет. Этот же скрипт пишет логи запросов и сообщает кому надо о подозрительной активности.

Непосредственного контакта клиентского приложения с СУБД быть не должно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы