песочница
От: MadHuman Россия  
Дата: 31.01.22 15:21
Оценка:
Всем здравия!
Есть задача в приложении исполнять пользовательский код (что-то типа плагинов), реализующий разные хотелки бизнес-логики.
Хочется для написания кода использовать C# и компилять код в сборку. Но требуется обеспечить безопасность, чтоб не могли делать сис вызовы в ОС, не могли лезть в файловую систему.
Есть вариант — поднимать рядом подпроцесс (возможно в контейнере), тогда всё получается, но для скорости хотелось бы инпроц (чтоб напрямую получать ссылки на объекты хост-приложения и тп).

Вообщем с вариантом 1 всё ясно, хотелось бы подумать/понять есть ли возможность обеспечить безопасность в случае инпроц исполнения этих плагинов (скомпиленного юзер-кода).
Ранее в .Net FW были домены, и там была возможность ограничить доступ к локальной файловой системы (и прочие возможности), но в коре их выпилили и не хотелось бы сейчас строить на их базе.
Поэтому остаётся вариант только предварительного анализа кода анализаторами, на предмет остуствия использования запрещённого.
С 1-го взгляда вроде задача решаемая, для этого — запретить создание/доступы к классам в определённых нэймспейсах, запретить рефлексию, запретить активаторы (чтоб по типу нельзя создать объект), запретить
использование dllimport. возможно что-то упустил, но вроде есть ощущение что задача конечная и решаемая...
Хотелось бы понять, если в этом направлении пойти, задача решаемая? кто что думает?
Re: песочница
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.01.22 16:03
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Вообщем с вариантом 1 всё ясно, хотелось бы подумать/понять есть ли возможность обеспечить безопасность в случае инпроц исполнения этих плагинов (скомпиленного юзер-кода).

MH>Ранее в .Net FW были домены, и там была возможность ограничить доступ к локальной файловой системы (и прочие возможности), но в коре их выпилили и не хотелось бы сейчас строить на их базе.
MH>Поэтому остаётся вариант только предварительного анализа кода анализаторами, на предмет остуствия использования запрещённого.
MH>С 1-го взгляда вроде задача решаемая, для этого — запретить создание/доступы к классам в определённых нэймспейсах, запретить рефлексию, запретить активаторы (чтоб по типу нельзя создать объект), запретить
MH>использование dllimport. возможно что-то упустил, но вроде есть ощущение что задача конечная и решаемая...
https://stackoverflow.com/questions/58468896/sandboxing-in-net-core
MH>Хотелось бы понять, если в этом направлении пойти, задача решаемая? кто что думает?
Две разных задачи, разные пути решения:
1. Изоляция сбоев. (Предположим, запускаемый код решил выполнить while(true);). Тут, как я понял, вариантов нет — отдельный процесс и всё.
2. Безопасность.
Тут, как я понял, варианты есть, но готовые мне неизвестны. Можно пойти разными путями:
1. Принимать код в виде исходников, парсить его при помощи Roslyn и анализировать AST
2. Принимать код в виде сборки, и анализировать MSIL.

В обоих подходах ищем небезопасные конструкции, и в случае чего делаем панику.
Детали зависят от того, что вы хотите разрешать делать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: песочница
От: MadHuman Россия  
Дата: 31.01.22 17:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>https://stackoverflow.com/questions/58468896/sandboxing-in-net-core

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

MH>>Хотелось бы понять, если в этом направлении пойти, задача решаемая? кто что думает?

S>Две разных задачи, разные пути решения:
S>1. Изоляция сбоев. (Предположим, запускаемый код решил выполнить while(true);). Тут, как я понял, вариантов нет — отдельный процесс и всё.
это неприятно (зацикливание), но не настолько опасно как доступ к файлам и функциям ОС.
в плохом варианте (когда зациклят), снизится перфоманс сервера, неприятно но не смертельно. процесс можно пристрелить, рестартовать.
вычислить какой плагин это делает и заблочить его.


S>2. Безопасность.

S>Тут, как я понял, варианты есть, но готовые мне неизвестны. Можно пойти разными путями:
S>1. Принимать код в виде исходников, парсить его при помощи Roslyn и анализировать AST
да, такой вариант и хочу, но нет уверенности что можно выявить / отследить все варианты опасного доступа.

пока рабочий вариант того что запретить:
— запретить вызовы по рефлексии.
— запретить создание инстансов через активатор.
— запретить dynamic
— запретить доступ к опасным классам (создание по new и вызов статических методов), типа File, Path, Directoty и тп
— запретить декларацию dllimport и тем самым нативные вызовы к ОС.

но не уверен, что этого достаточно.
если реализовать эти запреты, остаются ли варианты как их как-то обойти и всё таки создать/вызвать запрещённые объекты/методы?

вроде выглядит что достаточно, но почему тогда не гуглится что таким образом кто-то пытался реализовать ограничения? ненагуглил или есть фундаментальная проблема?
Re[3]: песочница
От: ltc  
Дата: 31.01.22 18:16
Оценка: +1
Здравствуйте, MadHuman, Вы писали:

S>>https://stackoverflow.com/questions/58468896/sandboxing-in-net-core

MH>спасибо. почитал, предлагается в отдельном процессе делать. как раз хотелось бы избежать этого.
MH>основная причина для избежания такого варианта — ожидается очень интенсивное взаимодействие с хостом и его данными (уже готовыми и лежащими в памяти).

Ну придется на MemoryMappedFiles что-то изобразить своё, решаемо.

S>>2. Безопасность.

S>>Тут, как я понял, варианты есть, но готовые мне неизвестны. Можно пойти разными путями:
S>>1. Принимать код в виде исходников, парсить его при помощи Roslyn и анализировать AST
MH>да, такой вариант и хочу, но нет уверенности что можно выявить / отследить все варианты опасного доступа.

MH>но не уверен, что этого достаточно.

MH>если реализовать эти запреты, остаются ли варианты как их как-то обойти и всё таки создать/вызвать запрещённые объекты/методы?

Мне кажется, потенциально опасное решение. Можно что-то забыть и получить свой log4j.
Раз у тебя отдельный процесс, пусть он будет с SIDом бесправного пользователя и работают встроенные механизмы безопасности.
Re: песочница
От: Kolesiki  
Дата: 31.01.22 22:04
Оценка: +2
Здравствуйте, MadHuman, Вы писали:

MH>в приложении исполнять пользовательский код (что-то типа плагинов)

MH>Но требуется обеспечить безопасность, чтоб не могли делать сис вызовы в ОС, не могли лезть в файловую систему

По-моему, это параноидальный перебор (с т.з. решения "хост-плагины"). По-идее, плагин — это тоже ЧАСТЬ ХОСТА, просто динамически загружаемая. Что умеет хост — то умеет плагин. А если это некие "недоверенные чёрные ящики", так им по-любому место в отдельных "бесправных" процессах + ваш хост, торчащий наружу микросервисами + RPC.

А что вообще за задача? А то опять мы решаем "авторское решение", которое он любезно предоставил из собственных мыслей! Может, там и плагинов-то никаких не надо — тупо запилить DSL и вот тебе полная секурность.
Re[3]: песочница
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.02.22 12:27
Оценка:
Здравствуйте, MadHuman, Вы писали:
S>>1. Изоляция сбоев. (Предположим, запускаемый код решил выполнить while(true);). Тут, как я понял, вариантов нет — отдельный процесс и всё.
MH>это неприятно (зацикливание), но не настолько опасно как доступ к файлам и функциям ОС.
MH>в плохом варианте (когда зациклят), снизится перфоманс сервера, неприятно но не смертельно. процесс можно пристрелить, рестартовать.
MH>вычислить какой плагин это делает и заблочить его.
Тут как раз проблема — в том, что прибивать придётся весь процесс, в котором не только плагин, но и основная логика.
Для того, чтобы прибивание процесса не повредило инварианты, придётся какие-то отдельные приседания делать. Иначе нарвётесь на что-нибудь типа того, что процесс выполнил какую-нибудь файловую операцию, позвал плагин — и завис. И в зависимости от того, насколько быстро watchdog пристрелит процесс, файловая операция может как доехать, так и не доехать до диска.
В итоге с какой-то вероятностью ваше приложение будет портить свои данные.

MH>пока рабочий вариант того что запретить:

MH>- запретить вызовы по рефлексии.
MH>- запретить создание инстансов через активатор.
MH>- запретить dynamic
MH>- запретить доступ к опасным классам (создание по new и вызов статических методов), типа File, Path, Directoty и тп
MH>- запретить декларацию dllimport и тем самым нативные вызовы к ОС.

MH>но не уверен, что этого достаточно.

MH>если реализовать эти запреты, остаются ли варианты как их как-то обойти и всё таки создать/вызвать запрещённые объекты/методы?
Если честно — то риск есть всегда. В основном — в виде всяческих транзитивностей. Например, вызов каких-нибудь десериализаторов: в "пользовательском" коде вызовов рефлексии нету, а вот в коде, который он импортирует — есть.
И так далее.
MH>вроде выглядит что достаточно, но почему тогда не гуглится что таким образом кто-то пытался реализовать ограничения? ненагуглил или есть фундаментальная проблема?
По соседству уже посоветовали начать от обратного: выяснить, что эти плагины должны делать, и попробовать прикрутить DSL (возможно, на основе чего-то готового вроде того же шарпа), в котором опасных конструкций просто нет совсем.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: песочница
От: MadHuman Россия  
Дата: 01.02.22 12:57
Оценка: -1
Здравствуйте, Sinclair, Вы писали:

S>Тут как раз проблема — в том, что прибивать придётся весь процесс, в котором не только плагин, но и основная логика.

S>Для того, чтобы прибивание процесса не повредило инварианты, придётся какие-то отдельные приседания делать. Иначе нарвётесь на что-нибудь типа того, что процесс выполнил какую-нибудь файловую операцию, позвал плагин — и завис. И в зависимости от того, насколько быстро watchdog пристрелит процесс, файловая операция может как доехать, так и не доехать до диска.
S>В итоге с какой-то вероятностью ваше приложение будет портить свои данные.
может быть и так. а может и нет. если воркер процесс делается стэйт-лесс, то такого не происходит. вообщем риск понятен, как обходить/избегать понятно.
более того, риск падения основного процесса часто и так присутсвует, так что проектровать и его стоит так чтоб минимизировать и избегать подобных последствий.


MH>>пока рабочий вариант того что запретить:

MH>>- запретить вызовы по рефлексии.
MH>>- запретить создание инстансов через активатор.
MH>>- запретить dynamic
MH>>- запретить доступ к опасным классам (создание по new и вызов статических методов), типа File, Path, Directoty и тп
MH>>- запретить декларацию dllimport и тем самым нативные вызовы к ОС.

MH>>но не уверен, что этого достаточно.

MH>>если реализовать эти запреты, остаются ли варианты как их как-то обойти и всё таки создать/вызвать запрещённые объекты/методы?
S>Если честно — то риск есть всегда. В основном — в виде всяческих транзитивностей. Например, вызов каких-нибудь десериализаторов: в "пользовательском" коде вызовов рефлексии нету, а вот в коде, который он импортирует — есть.
он импортирует строго ограниченное подмножество.

S>По соседству уже посоветовали начать от обратного: выяснить, что эти плагины должны делать, и попробовать прикрутить DSL (возможно, на основе чего-то готового вроде того же шарпа), в котором опасных конструкций просто нет совсем.

там советует известный местный токсик, с которым вести дискуссии неплодотворно. но этот путь уже пройден, те варианты для которых можно было DSL — уже есть DSL (аля редактор бизнесс-процессов), но в некоторых кейсах надо больше гибкости и следующий шаг — перейти к коду.
вообще тема холиварная и мой вопрос не в ней, она уже подробно разобрана, см. например в СВ про Дракон.
Re[5]: песочница
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.02.22 14:40
Оценка: 6 (1)
Здравствуйте, MadHuman, Вы писали:


MH>>>но не уверен, что этого достаточно.

MH>>>если реализовать эти запреты, остаются ли варианты как их как-то обойти и всё таки создать/вызвать запрещённые объекты/методы?
S>>Если честно — то риск есть всегда. В основном — в виде всяческих транзитивностей. Например, вызов каких-нибудь десериализаторов: в "пользовательском" коде вызовов рефлексии нету, а вот в коде, который он импортирует — есть.
MH>он импортирует строго ограниченное подмножество.
А что именно он импортирует? Надо смотреть, не завелось ли там чего-то, что можно творчески эксплуатировать.
Вон, никто же не ожидал, что в Адобовском коде интерпретации шрифтовых хинтов можно выполнить stack underflow и выполнить злонамеренный код под правами текущего пользователя.

MH>там советует известный местный токсик, с которым вести дискуссии неплодотворно.

Я стараюсь меньше обращать внимания на людей, и больше — на идеи.
MH>но этот путь уже пройден, те варианты для которых можно было DSL — уже есть DSL (аля редактор бизнесс-процессов), но в некоторых кейсах надо больше гибкости и следующий шаг — перейти к коду.
Не очень понятно противопоставление DSL и кода. Ведь в слове DSL главная буква — это L. Если не хватает мощности языка — всегда можно в него что-то добавить.
Это проще, чем убирать из языка.
Тем более, что, возможно, анализировать надо будет не C#, а MSIL. Я вот сходу не возьмусь напилить с нуля анализатор, который бы отлавливал всё опасное (надо смотреть, к примеру, как именно выглядит dynamic на уровне MSIL)
MH>вообще тема холиварная и мой вопрос не в ней, она уже подробно разобрана, см. например в СВ про Дракон.
Дракон тут имхо ортогонален вопросу. Он же не про безопасность, а про определённую графическую нотацию, которая предотвращает синтаксические ошибки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: песочница
От: vaa  
Дата: 02.02.22 08:17
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Хочется для написания кода использовать C#


сишарп итак мало что может, а вы его еще хотите обрезать.
Для бизнес логики обычно используют скриптинг.
только операции с объявленными объектами и примитивными типами(строки, числа, даты).
типа: salesforce scripting language
еще видел в дельфи какой-то паскаль, на котором писались формулы для компонентов midas
ну и 1с.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: песочница
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.02.22 00:34
Оценка: 2 (1) +1
Здравствуйте, MadHuman, Вы писали:

MH>Хочется для написания кода использовать C# и компилять код в сборку. Но требуется обеспечить безопасность, чтоб не могли делать сис вызовы в ОС, не могли лезть в файловую систему.


Создать список допустимых типов (или типов и методов) и конструкций (например, DllImport в топку). Обрабатывать код Розлином и через визитер проверять, что вызваны методы исключительно из списка разрешенных. Как вариант, принимать на вход готовые сборки и сделать их анализатор на базе dnLib.

MH>Есть вариант — поднимать рядом подпроцесс (возможно в контейнере), тогда всё получается, но для скорости хотелось бы инпроц (чтоб напрямую получать ссылки на объекты хост-приложения и тп).


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

ЗЫ

Но вообще, это паранойя. Если у юзеря есть права на машине он может и без ваших плагинов наворотить дел или нарваться на вредоносное ПО. У вас код плагинов из не вызывающих доверия источников может приходить? Вы сборки подписываете, кстати? Если нет, то вам и так можно подсунуть все что угодно. Дотнетные процессы вообще не надежны. Вам могут подсунуть вредоносный код внедрив его в код фрэймворка.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: песочница
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.02.22 08:54
Оценка: +1
Здравствуйте, vaa, Вы писали:

vaa>ну и 1с.


Ну в 1С можно нетовские библиотеки напрямую использовать!
Использование классов .Net в 1С для новичков
и солнце б утром не вставало, когда бы не было меня
Re[3]: песочница
От: vaa  
Дата: 09.02.22 09:03
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Ну в 1С можно нетовские библиотеки напрямую использовать!

S>Использование классов .Net в 1С для новичков
Логично, .net это развитие COM-технологии.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: песочница
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.02.22 10:26
Оценка: 3 (1)
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, Serginio1, Вы писали:


S>>Ну в 1С можно нетовские библиотеки напрямую использовать!

S>>Использование классов .Net в 1С для новичков
vaa>Логично, .net это развитие COM-технологии.
Неее. В .Net сделано удобное использование и совмещение с СОМ
СОМ это межьязыковой стандарт со своим менеджером памяти аппартаментами и прочими плюшками.
Вот как раз с СОМ .Net плохо совметим ибо Release нужно вручную вызывать, а не автоматом как это делается в нативных языках.
Приходится много приседаний делать.

Кстати ы 1С сделали возможность вызывать COM в песочнице
и солнце б утром не вставало, когда бы не было меня
Отредактировано 09.02.2022 10:59 Serginio1 . Предыдущая версия .
Re[2]: песочница
От: MadHuman Россия  
Дата: 09.02.22 10:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, MadHuman, Вы писали:


MH>>Хочется для написания кода использовать C# и компилять код в сборку. Но требуется обеспечить безопасность, чтоб не могли делать сис вызовы в ОС, не могли лезть в файловую систему.


VD>Создать список допустимых типов (или типов и методов) и конструкций (например, DllImport в топку). Обрабатывать код Розлином и через визитер проверять, что вызваны методы исключительно из списка разрешенных. Как вариант, принимать на вход готовые сборки и сделать их анализатор на базе dnLib.

да, так и думаю делать (обрабатывать анализатором). есть анализатор BannedApiAnalyzers как раз позволяет выявлять и запрещать заданные типы/методы.


VD>Тут вопрос в задаче, которую нужно было описать. Если, например, вопрос в обработке каких-то данных, то межпроцессный вызов для передачи результатов может быть не особо критичным. Скажем кладешь данные в файл. Вызываешь метод плагина по RPC и передаешь ему пути к входному и выходному файлу. По завершении читаешь получившийся файл. В общем, главное не делать очень много вызовов к серверу. Если это десятки в секунду и данные не огромные, то вполне потянет по RPC.

это понятно. в задаче как раз требуется много мелких взаимодейтсвий с 100500 функциями/пропертями хоста и часто выполняющихся (много тысяч в сек) .



VD>Но вообще, это паранойя. Если у юзеря есть права на машине он может и без ваших плагинов наворотить дел или нарваться на вредоносное ПО. У вас код плагинов из не вызывающих доверия источников может приходить? Вы сборки подписываете, кстати? Если нет, то вам и так можно подсунуть все что угодно. Дотнетные процессы вообще не надежны. Вам могут подсунуть вредоносный код внедрив его в код фрэймворка.

у нас юзер присылает исходник который мы затем на лету компиляем в инмемори асембли и юзаем, не готовую сборку.
пока мне видится что анализатором можно ограничить всё что нужно, и это проще чем заморачиваться выделением в подпроцесс и организацией маршалинга для 100500 методов/пропертей апи хоста.
Re: песочница
От: IQuerist Мухосранск  
Дата: 02.03.22 10:03
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Всем здравия!

MH>Есть задача в приложении исполнять пользовательский код (что-то типа плагинов), реализующий разные хотелки бизнес-логики.

Добро пожаловать в мир DSL.
Re: песочница
От: Слава  
Дата: 02.03.22 12:14
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Хотелось бы понять, если в этом направлении пойти, задача решаемая? кто что думает?


Только out-of-process с обрезанными в ноль правами. Или же пишите плагины на Идрисе, с обязательной тотальностью в коде (разумеется этого делать никто не будет).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.