Pull to refresh

Comments 13

API, который позволял пользователям исполнять код на R

Ну, собственно, дальше можно и не читать, тем более что статья короткая. И верно - что там ещё можно написать?

API, позволяющий исполнять код - сразу дыра. Точнее - тоннель, как автор его и использовал.

Много лет назад на фрилансе заказчик попросил сделать сервис, где пользователи могли бы исполнять свои небольшие части Python-кода по обработке данных. Этакий ETL в облаке - тогда ещё было не так много таких сервисов..

Естественно, я попытался обрезать все возможные способы вылезти в систему - через ast/inspect валидировал код, позапрещал использование модулей типа os, sys и тп, вдобавок из builtins вырезал open, dir, setattr и всё потенциально нехорошее. Однако, был нужен, например, pandas - после нескольких попыток позапрещать функции и там, я сдался - обычным read_csv там можно было тоже, при желании, натворить дел. Были варианты собирать свой Python, который не разрешает доступ к ФС, но это уже слишком много работы для одного человека.

Зато сделал для себя вывод, что такие API совершенно небезопасны.

Зато сделал для себя вывод, что такие API совершенно небезопасны.

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

Контейнер не панацея, если пользователь ничем больше не ограничен. Вспоминаем про Spectre, Meltdown и компанию.

Патчи уже есть для них. Те кто продает такие штуки их поставили и снижение производительности учли в цене. То есть опять зиродей уязвимость нужна.

Зиродей с настолько сложной эксплуатацией и облачным окружением со случайными соседями ну такое себе. Там еще и крупных систем с по настоящему интересными данными нет. Они такое не используют для продакшена.

В целом сойдет. Не всегда и не для всех, но сойдет.

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

А он не будет искать ваши данные. Оно просто войдёт в ботнет и будет ддосить других

Слово фаервол вам что-нибудь говорит? Сходить можно максимум к соседу в такую же песочницу или в базу где почты юзеров лежат.

Все еще так себе цель для зиродея.

Ну ок, за ваши сервера я спокоен - вы знаете слово "фаервол".

Тем не менее, первое, что можно проверить при получении доступа на любом сервере - доступ в интернет и к соседним хостам.

Возьмём, к примеру, AWS - у вас есть внутренняя сеть вида, например, 172.31.0.0/16 (дефолт). Снаружи доступ к серверам ограничен через Security Group, но внутри сети правила могут быть слабее. Даже если вы запускаете какой-то код внутри Docker-контейнера - это не помешает ему отправить запросы к соседним серверам и они будут идти внутри сети, как будто бы от имени этого сервера. Также можно попробовать, например, AWS Magic URL - если, например, на сервере установлена роль, разрешающая доступ, то там тоже можно интересным заняться.

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

Контейнеры имеют тенденцию со временем становиться более безопасными и простыми в использовании. Тот же play.rust-lang.org просто запускает docker с --net none, здесь сложно что‐то забыть или неправильно настроить.

Да, я сначала вообще решил что там на Javascript просто интерпретатор в браузере, но потом тоже посмотрел в гитхабе (не поверил вам на слово, простите).

Тем не менее, это получается вообще совсем песочная песочница - с сетью не поработать и пакетов никаких дополнительных не поставить. Только для Hello World подойдёт. Либо ставь для использования внутри компании, но тогда это не публичный апи.

Для того, чтобы показать на форуме, как вы можете написать рекурсивный макрос или ещё чего интересное, достаточно. Если нужно какой‐то доступ к сети, я бы смотрел так:

  1. Есть ли готовые пакеты с решением проблемы? Я не уверен, как сформулировать такой запрос, но когда я искал, а что делают сервисы CI (а они по сути как раз запускают у себя недоверенный клиентский код, которому нужен интернет), я нашёл только что они либо закрытые, либо предполагают внутреннее использование (в смысле внутри компании (с закрытой регистрацией), разработчики не менее чем одного найденный OpenSource CI сервера вполне предполагает, что он будет торчать в интернет). Я ещё посмотрел в сторону OpenSource облаков, но они слишком сложные.

  2. Если ничего не найдено, то можно попытаться сделать так:

    1. Пускать контейнер «без сети». Нет сети — не нужны настройки firewall для контейнера, и соответственно, не нужно думать, как объяснить firewall’у, чего вы от него хотите, если вы хотите чего‐то вроде «не более N запросов в секунду от одного пользователя».

    2. В контейнере подменить библиотеки, работающие с сетью, на что‐то, что будет заворачивать запросы в stdout/unix socket/…, что общается с сервером, запустившим контейнер. Если подменить библиотеки нельзя, можно сделать виртуальный сетевой интерфейс, который будет делать то же самое, но уже ниже уровнем.

    3. На сервере уже реализовать собственно общение с интернетом, со сбором интересных метрик и со своими ограничениями — по сути firewall будет тут.

    Мне кажется, такой вариант проще в реализации, потому что серверу, запускающему контейнер уже отлично известно, почему (по какому запросу) он его запустил, так легче собрать метрики с привязкой к контейнерам/пользователям/запускаемому в контейнере коду.

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

В общем, да, всё так, ничего не могу добавить к вашим рассуждениям.

Опять же - это если делать всё правильно, с хорошими специалистами. Не всегда есть возможность привлечь эксперта по конкретной теме, и в итоге в продакшен идут системы, в которых возможны уязвимости - на них и расчитаны все эти атаки.

Чтобы это не было тоннелем можно, как написали выше, использовать контейнеры. Как пример успешной реализации: https://play.rust-lang.org (https://github.com/rust-lang/rust-playground), можете поискать уязвимости и сообщить разработчикам, если найдёте. Использует docker.

Название статьи начинается "как я нашёл...". Так а какие методы используются для поиска подобного?

Sign up to leave a comment.

Articles