Comments 35
Хмм, идея интересная, были мысли сделать библиотеку на подобии такой.
Посмотрите мой топик про .NET компилятор. Так в принципе можно и не только эти языки сделать.
Также видел проект, рисующий графики функций, который компилит их «в уме».
Посмотрите мой топик про .NET компилятор. Так в принципе можно и не только эти языки сделать.
Также видел проект, рисующий графики функций, который компилит их «в уме».
Простите, ссылку съели: habrahabr.ru/blogs/crazydev/113215/
Реализация подобного рода скриптования может быть опасной, поскольку из скриптов афайк может быть доступ к внутренним методам и данным приложения.
Об этом как раз сказано в заключении. Там же есть и решение — правильно настраивать уровни видимости — то, что к чему нельзя подпускать делаем internal. Правда защита такого плана обходится при помощи рефлексии. Сейчас как раз ищу способы защиты от такого.
Скрипт можно запустить из отдельного домена с минимальным набором разрешений.
Можно. Но это .NET 4.0. Что накладывает некоторые ограничения.
Прошу прощения, AppDomain есть в любой версии .NET. То ли MSDN проглючило, то ли меня…
Домены есть даже в .NET 1.1 — http://msdn.microsoft.com/ru-ru/library/system.appdomain(v=VS.71).aspx
Скрипт нужно запускать в отдельном домене. Не только разрешения, но и стабильность выполнения.
Стабильность в каком смысле? Это ведь управляемый код.
Управляемый код, тем не менее, вполне может сожрать память, впасть в бесконечный цикл и предоставить прочие прелести программистских ошибок.
Отдельный апп-домен вы в любой момент можете выгрузить, даже если живущий в нем тред завис.
Отдельный апп-домен вы в любой момент можете выгрузить, даже если живущий в нем тред завис.
Не в любой момент, насколько я знаю. Если тред завис на выполнении неуправляемого кода или исполнении finally блока, домен выгрузить не удастся.
Код в другом AppDomain тоже может сожрать память. Хотя, если это контролировать, можно попробовать успеть его выгрузить.
Код в другом AppDomain тоже может сожрать память. Хотя, если это контролировать, можно попробовать успеть его выгрузить.
«Если тред завис на выполнении неуправляемого кода или исполнении finally блока, домен выгрузить не удастся.»
А если завис ваш собственный тред, вы не можете его выгрузить никогда. И это большая разница.
Плюс Рихтер пишет (CLR via C#, 3rd Edition, глава Writing Robust Host Applications), что в четвертом фреймворке можно сделать escalation policy, который приведет к тому, что если домен нельзя положить «по правилам», его убьют без правил. И это еще один аргумент за отдельные домены.
«Код в другом AppDomain тоже может сожрать память.»
Тем не менее, контроля за ним у вас намного больше.
А если завис ваш собственный тред, вы не можете его выгрузить никогда. И это большая разница.
Плюс Рихтер пишет (CLR via C#, 3rd Edition, глава Writing Robust Host Applications), что в четвертом фреймворке можно сделать escalation policy, который приведет к тому, что если домен нельзя положить «по правилам», его убьют без правил. И это еще один аргумент за отдельные домены.
«Код в другом AppDomain тоже может сожрать память.»
Тем не менее, контроля за ним у вас намного больше.
По поводу безопасности — могу дать несколько советов которые возможно вам помогут
1. Во первых класс «плагина» должен реализовывать ранее продуманный интерфейс. И этот класс должен предусматривать некий «менеджер» который будет отвечать за доступ к важным данным и функциям основного приложения.
2. Доступ к файлику с паролями стоит ограничить. Как минимум приложение может его просто блокировать в начале работы и разблокировать после выгрузки «плагинов» (вариант грубый но простой)
3. Если есть критические данные в базе — то не давать доступа к connection string а опять же работать через менеджер которые дает возможность реализовать безопасный доступ к данным и контролировать операции из основного приложения.
4. Ну и еще есть вариант подписи плагинов — то есть прежде чем плагин выпустить в свободное плавание — его исходный код изучает специалист и проверяет на потенциально опасный код. Такая система например с приложения в App Store от Apple. (Хотя опять же зависит от конкретной ситуации — подходит такой вариант, или нет)
1. Во первых класс «плагина» должен реализовывать ранее продуманный интерфейс. И этот класс должен предусматривать некий «менеджер» который будет отвечать за доступ к важным данным и функциям основного приложения.
2. Доступ к файлику с паролями стоит ограничить. Как минимум приложение может его просто блокировать в начале работы и разблокировать после выгрузки «плагинов» (вариант грубый но простой)
3. Если есть критические данные в базе — то не давать доступа к connection string а опять же работать через менеджер которые дает возможность реализовать безопасный доступ к данным и контролировать операции из основного приложения.
4. Ну и еще есть вариант подписи плагинов — то есть прежде чем плагин выпустить в свободное плавание — его исходный код изучает специалист и проверяет на потенциально опасный код. Такая система например с приложения в App Store от Apple. (Хотя опять же зависит от конкретной ситуации — подходит такой вариант, или нет)
1. Во первых класс «плагина» должен реализовывать ранее продуманный интерфейс. И этот класс должен предусматривать некий «менеджер» который будет отвечать за доступ к важным данным и функциям основного приложения.
2. Доступ к файлику с паролями стоит ограничить. Как минимум приложение может его просто блокировать в начале работы и разблокировать после выгрузки «плагинов» (вариант грубый но простой)
Предыдущий комент почему-то самопроизвольно отправился…
Как раз такого подхода я и хочу добиться. Здесь проблема в том, что надо запретить в коде сточки вида System.IO.FileStream file = new System.IO.FileStream(«путь_до_важного_файла_с_паролями»);
В статье я имел в виду файлы паролей не только самого приложения. Например — файл %APPDATA%/Opera/Opera/wand.dat. Не очень хорошо будет если такой файл попадёт не в те руки.
К сожалению в моём случае не подходит.
1. Во первых класс «плагина» должен реализовывать ранее продуманный интерфейс. И этот класс должен предусматривать некий «менеджер» который будет отвечать за доступ к важным данным и функциям основного приложения.
Как раз такого подхода я и хочу добиться. Здесь проблема в том, что надо запретить в коде сточки вида System.IO.FileStream file = new System.IO.FileStream(«путь_до_важного_файла_с_паролями»);
2. Доступ к файлику с паролями стоит ограничить. Как минимум приложение может его просто блокировать в начале работы и разблокировать после выгрузки «плагинов» (вариант грубый но простой)
В статье я имел в виду файлы паролей не только самого приложения. Например — файл %APPDATA%/Opera/Opera/wand.dat. Не очень хорошо будет если такой файл попадёт не в те руки.
4. Ну и еще есть вариант подписи плагинов — то есть прежде чем плагин выпустить в свободное плавание — его исходный код изучает специалист и проверяет на потенциально опасный код. Такая система например с приложения в App Store от Apple. (Хотя опять же зависит от конкретной ситуации — подходит такой вариант, или нет)
К сожалению в моём случае не подходит.
Внезапно в топик врывается кодогенерация через System.Linq.Expressions и DLR, который для реализации скриптов и придумали (см. IronPython, IronRuby и прочее).
Сразу, чтобы отмести обвинения в .net 4-only, DLR изначально был реализован в виде отдельной библиотеки — dlr.codeplex.com/
В Mono работает.
А System.CodeDom.Compiler изначально был нужен для кодогенерации именно в компиляторах.
Давайте все-таки использовать инструменты по назначению.
Сразу, чтобы отмести обвинения в .net 4-only, DLR изначально был реализован в виде отдельной библиотеки — dlr.codeplex.com/
В Mono работает.
А System.CodeDom.Compiler изначально был нужен для кодогенерации именно в компиляторах.
Давайте все-таки использовать инструменты по назначению.
В целом верно. Сам зашел в этот пост чтобы проверить, предложено ли это очевидное (для меня) решение.
А что вы можете добавить по ограничению прав такого скрипта?
А что вы можете добавить по ограничению прав такого скрипта?
Кроме того, почти все классы из System.CodeDom.Compiler недоступны в Silverlight, например.
Спасибо за ещё одно направление в котором нужно подумать. До этого так нормально и не знал для чего предназначен DLR. Сейчас посмотрел его поверхностно — позже посмотрю поподробнее. Однако мне кажется что любой подход имеет право на существование — в качестве плюсов к моему методу могу сказать что у меня уже сразу используется готовый язык. В случае DLR же, если я правильно понял, надо ещё описать синтаксис языка, и что во что компилируется.
У моно есть же специальное безопасное решение для создания песочниц с поддержкой CoreCLR и прочего. Они на его основе безопасность в мунлайте делали.
> я мог править код, на лету перекомпилируя его прямо в своём приложении
Any sufficiently complicated program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
Any sufficiently complicated program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
посмотрите на Boo — его вроде как немного забросили, но он позволяет делать и более сложные штуки без такого шаманства.
Немного не в тему, но какие библиотеки Вы использовали для работы с Lua? Я пару лет назад использовал LuaInterface, было очень удобно. Никакой кучи биндингов. Правда я не уверен на счёт его работы с моно.
Кстати, если не ошибаюсь, сгенерированный раз код так и остается висеть в памяти, поскольку отдельную сборку в .NET выгрузить нельзя. Только AppDomain целиком. Так что домен все равно желательно создавать. Но тогда доступ к функциям сборки будет несколько затруднен?
Я честно говоря думал что сборка автоматом выгрузится сборщиком мусора. А по поводу затруднения доступа — есть такое. Если я правильно понял — то из домена можно либо запустить на выполнение exe, либо создать экземпляр какого либо объекта и уже с ним работать. Если я правильно понял — то просто вызвать статический метод — нельзя (если он не является точкой входа)
«Я честно говоря думал что сборка автоматом выгрузится сборщиком мусора.»
Зря вы так думали. .net framework не умеет выгружать отдельные сборки из домена, только домен целиком.
«Если я правильно понял — то из домена можно либо запустить на выполнение exe, либо создать экземпляр какого либо объекта и уже с ним работать. Если я правильно понял — то просто вызвать статический метод — нельзя (если он не является точкой входа) „
Это-то мелочи. В реальности вы вообще (к счастью) не можете протащить через границу домена ни один объект, не попадающий под определенные ограничения.
Зря вы так думали. .net framework не умеет выгружать отдельные сборки из домена, только домен целиком.
«Если я правильно понял — то из домена можно либо запустить на выполнение exe, либо создать экземпляр какого либо объекта и уже с ним работать. Если я правильно понял — то просто вызвать статический метод — нельзя (если он не является точкой входа) „
Это-то мелочи. В реальности вы вообще (к счастью) не можете протащить через границу домена ни один объект, не попадающий под определенные ограничения.
Sign up to leave a comment.
Скрипты в .NET/Mono средствами самой платформы