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

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

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

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

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

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

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

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

Или надпись «Take One», висящая на тарелке с отдельными кеглями на Хэллоуин.


person Mike Webb    schedule 26.01.2011    source источник
comment
Можете ли вы отклонить плагин, если он ссылается на dll Windows.Form?   -  person hungryMind    schedule 26.01.2011
comment
@hungryMind Если кто-то использует отражение для доступа к типам, легко обойти проверки ссылок. Строковые атаки обходят это.   -  person Tim Lloyd    schedule 26.01.2011


Ответы (4)


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

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

Обновить

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

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

Этот подход ни в коем случае не тривиален, но как только вы освоите основы, он не будет слишком сложным.

Обновление 2

Что-то изменилось с тех пор, как в свое время вы развернули свои собственные фреймворки плагинов с помощью AppDomins. Начиная с версии 3.5, в .Net framework встроена поддержка плагинов:

MAF — Managed Addin Framework / System.Addin

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

person Tim Lloyd    schedule 26.01.2011
comment
Есть ли пример веб-сайта или что-нибудь, объясняющее, как установить эту ограниченную безопасность? Есть ли способ общения между ними? - person Mike Webb; 27.01.2011
comment
@Mike Я только что искал хорошие примеры самодельных архитектур плагинов с AppDomains. Прошло много времени с тех пор, как я использовал это для написания фреймворка для плагинов, и многие образцы, которые я нашел, были проблематичными. Это действительно довольно сложно сделать правильно, поэтому я не хотел обременять вас примерами, которые заставят вас рвать на себе волосы. Затем я вспомнил, что MS фактически внедрила структуру плагинов в .Net 3.5 — MAF: Managed Addin Framework. Этот фреймворк имеет дело с большим количеством грязи из коробки, поэтому вам не нужно, например. Изоляция AppDomain и загрузка\выгрузка плагинов. - person Tim Lloyd; 27.01.2011
comment
@Mike Поскольку это среда MS, есть тонны документации и онлайн-контента, что намного лучше. Хорошее начало здесь: msdn.microsoft.com/en-us/magazine/ cc163476.aspx. - person Tim Lloyd; 27.01.2011
comment
Пока я ограничен использованием .NET 2.0, но кое-что нашел. С помощью некоторого пользовательского кода, основанного на концепциях, использованных в этих статьях, я думаю, что смогу написать архитектуру плагина, используя передачу sudo-сообщений. Во второй части представлен код для использования AppDomains. Вот веб-сайт: 15seconds.com/issue/040624.htm - person Mike Webb; 27.01.2011
comment
@Mike OK .Net 2.0 - System.Addin отсутствует. Хорошо Ре. AppDomains, в этой статье есть много информации, которая поможет вам начать работу, хотя есть некоторые комментарии о загрузке сборок в домен по умолчанию — все же некоторые очень хорошие основы: codeproject.com/KB/cs/dynamicpluginmanager.aspx - person Tim Lloyd; 27.01.2011

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

person Jon Skeet    schedule 26.01.2011

Итак, чтобы еще раз сформулировать вашу основную проблему:

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

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

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

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

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

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

ОБНОВЛЕНИЕ

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

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

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

person csharptest.net    schedule 26.01.2011
comment
Я вижу смысл в другом процессе, использующем вызовы Win32 и внедрение кода, но если вы загружаете плагин в AppDomain, который настроен с ограниченными разрешениями (например, без разрешения UnmanagedCode), как он может использовать этот вектор? - person Tim Lloyd; 27.01.2011
comment
Из-за характера SO-уведомлений было бы полезно обратиться к моему @username, иначе я не буду уведомлен о вашем ответе. Я сделал свой комментарий, поскольку тон вашего ответа может заставить людей думать, что использование AppDomains было безнадежным делом. инъекция кода. - person Tim Lloyd; 27.01.2011

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

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

person Sam Harwell    schedule 26.01.2011