Есть ли способ заблокировать плагин C# от доступа к основному приложению C# в программе?

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

Я не использую MEF Microsoft, и у меня есть причины не делать этого. На этом я остановлюсь.

проблема в том, что когда Плагины загружаются, независимо от того, насколько они "слепы" к основному программа и ее формы / классы / etc. он все еще может получить доступ System.Windows.Forms.Application и поэтому может получить доступ к моему приложению и его текущим формам/методам/элементам управления/и т. д.

Я не хочу этого. Есть ли способ ограничить доступ плагина к основному приложению?

EDIT: дополнительная информация о плагине

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

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

или знак "Take One", висящий на чаше отдельных кегельбанов на Хэллоуин.

4 ответов


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

дополнительное преимущество, которое вы получаете от хостинга AppDomain, заключается в том, что вы можете загружать и выгружать эти домены, если хотите обновить плагины, а также защитить свой основной AppDomain от сбоев в ваши" детские " Домены.

обновление

после просмотра вашего обновления re. возможности вашего плагина, AppDomains не помогут, если ваш плагин должен иметь прямой доступ к элементам пользовательского интерфейса, например, доступ к форме для добавления элементов управления. Вы не сможете предоставить прямой доступ к форме через границу AppDomain или создать элементы управления в одном AppDomain, а затем маршалировать их в другой.

вы все еще можете рассмотреть возможность размещения плагинов в другом AppDomain, но вам нужно будет подумать о каком-то прокси-механизме, чтобы такие действия, как добавление элемента управления в форму, могли быть сделаны от имени плагина, а не позволять плагину напрямую обращаться к форме. Например, вы можете передать объект Form builder с такими методами, как AddButton. Затем прокси-сервер может выполнять эти действия от имени плагина в главном домене. Таким образом, вы можете предоставить ограниченный API для плагина в комплекте с требуемым события.

этот подход отнюдь не тривиален, но как только вы освоили основы, это не слишком сложно.

обновление 2

все пошло дальше с момента прокатки собственных рамок плагинов с AppDomins в тот же день. Теперь есть поддержка, запеченная в .Net framework с 3.5 для плагинов:

MAF-управляемый Addin Framework / System.Addin

Он поддерживает режимы изоляции AppDomain для plugins и имеет загрузчики плагинов и т. д. Нет необходимости сворачивать свой собственный.


Если вы можете запускать свои плагины самостоятельно AppDomains, Это, безусловно, повысит уровень изоляции. Это также может сделать его боль, чтобы общаться с ними, хотя. Не зная больше о том, для чего предназначены Плагины, трудно понять, подходит ли это.


Так переформулировать основной вопрос:

... и поэтому может получить доступ к моему приложению и его текущим формам/методам/элементам управления/и т. д.

прежде чем приступать к сложным и сложным средствам загрузки, изоляции и ограничения этих расширений, вы должны знать несколько вещей о Windows и CLR. Во-первых, любая программа, работающая на коробке, может использовать несколько API Windows для ввода кода в ваш процесс. После загрузки кода в ваш процесс, либо вами, либо ОС, доступ к среде выполнения CLR и загрузке сборок и/или запуску кода в существующем AppDomain довольно прост.

зная это, вы должны взвесить и сбалансировать усилия, которые вы выдерживаете, чтобы ограничить "расширения". Если бы я строил что-то подобное, я бы больше беспокоился о других вещах, чем о вредоносном коде расширения, манипулирующем состоянием моего приложения. Например, это вещи, которые вы могли бы подумайте:

  1. загружайте только те расширения, которые одобрены вашим пользователем, разрешайте им контролировать то, что разрешено, и разрешайте им отменять расширение позже, если это необходимо. Посмотрите на Office или VStudio в качестве примера.
  2. убедитесь, что эти утвержденные расширения не повреждены с помощью требования подписи кода (строгие имена или сертификаты подписи кода).
  3. рассмотрите возможность отмены возможности удаленного запуска расширения, если установлено, что оно злонамеренный.
  4. докажите хорошо назначенный интерфейс API, чтобы разработчики могли легко реализовать желаемое поведение. Если им легко использовать ваши интерфейсы для выполнения своей задачи, им не нужно будет "взломать".

кроме этого, на самом деле вы ничего не можете сделать. Как я уже сказал, Любой может атаковать ваше приложение даже с вышеуказанными охранниками. Ваша главная задача-не удивлять пользователей. Таким образом, должная забота о том, в каком коде работает ваше приложение желательно, но то, что эти расширения делают, как только ваши пользователи предоставляют им доступ, на самом деле не является тем, что вы можете полностью контролировать.

Это не означает, что изоляция AppDomain не обеспечит вам ценность, это может быть; однако, ИМХО получение безопасности достаточно ограничено без ограничения их способности функционировать окажется сложным.

обновление

... но если вы загружаете плагин в AppDomain, который настроен с ограниченным разрешения как он может использовать этот вектор?

правильно, как я сказал в своих заключительных заявлениях, вы можете ограничить их доступ к неуправляемому коду в AppDomain. Это также ограничивает их способность разрабатывать полезный опыт Windows. Я ожидаю, что большинство приложений WinForms используют по крайней мере один вызов PInvoke или неуправляемый com-элемент управления. Это ограничение может быть приемлемым, я действительно не могу сказать без дополнительной информации о том, какую функциональность они пытаются обеспечивать.

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


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

ниже приведены внешние крючки пользовательского интерфейса для WPF, Windows Forms и классического Spy++ (все с исходным кодом).