2012-05-28 1 views
3

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

Мне нужен безопасный серверный скриптовый язык. Мне нужно иметь доступ к константам и значениям из таблиц базы данных 4+, результаты предыдущих вычислений, определять пользовательские переменные и функции, использовать выражения if/then/else, и я уверен, что я не могу думать о правильном Теперь.

Некоторые опции я Рассмотренные:

  1. Я рассмотрел использовать что-то вроде this matheval library, но я бы в конечном итоге нужно продлить его значительно для моего использования. По существу я бы создал свой собственный язык.

  2. PHP runkit sandbox. Я никогда не использовал это раньше, но я очень обеспокоен проблемами безопасности. Учитывая возможные проблемы с безопасностью, я не думаю, что это жизнеспособный вариант.

  3. Еще одна идея, которая пришла мне в голову, что я не знаю, возможно ли это, использовать на сервере что-то вроде javascript. Я видел, что js используется в качестве платформы сценариев в настольных приложениях для расширения функциональности, и похоже, что подобный подход может быть осуществим. Я мог бы в идеале определить среду, в которой все это выполнялось, например, отключить доступ к файловой системе и т. Д. Опять же, безопасность кажется такой проблемой.

Из исследования, которое я сделал, похоже, что № 1, вероятно, является моим единственным вариантом, но я думал, что я проверил бы с большим пулом талантов. :-)

Если # 3 возможно, кажется, что это будет путь, но я не могу показать ничего полезного. С другой стороны, между № 2 и № 3 не может быть большой разницы.

Производительность - еще одно соображение. Будет около 65 некоторых нечетных формул, каждый из которых будет выполняться около 450 раз. Каждая формула будет иметь доступ к приблизительно 15 уникальным переменным сотню констант и результатам предыдущих формул. (Да, существует конкретный порядок выполнения.)

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

Каков наилучший способ работы с этой ситуацией? Существуют ли какие-либо другие сторонние библиотеки, которые я не обнаружил в своих исследованиях? Есть ли еще один вариант в дополнение к моим 3, который я должен рассмотреть?

+0

Посмотрите узел.js. «Еще одна идея, которая перешла мне на ум, что я не знаю, возможно ли это использовать что-то вроде javascript на стороне сервера». –

+0

@MrSmith Я не знаком с node.js. Не могли бы вы немного объяснить? Из того, что я понимаю в node.js, он полностью сопоставим с PHP. Разве у меня не было бы проблем с безопасностью, связанных с 'eval'? – Icode4food

+0

У symfony2 twig есть набор инструментов DSL, поэтому вы можете создать свой собственный язык легко и на чистом PHP. – hakre

ответ

1

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

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

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

Если есть функция или подзаголовок, которые вы не хотите использовать, вы можете определить ее перед отключением внешнего кода. Не хотите, чтобы они использовали «читать» для чтения файла? read = func(s) { }

Очевидно, что вам следует поговорить с списками рассылки JS-реализации, которые вы хотите использовать, чтобы получить некоторые советы по ее лучшей защите.

Но JS имеет хорошую поддержку, хорошо документирована, и переводчики действительно доступны.

+0

Просто хочу упомянуть, что функции undefining на самом деле не являются безопасным способом защитить пользователя от доступа к ним. Правильный способ - использовать изолированную среду, такую ​​как ограниченный подпроцесс для Node.js или изолированный iframe в браузере. Есть несколько библиотек, упрощающих задачу, из созданных мной: [https://github.com/asvd/jailed](https://github.com/asvd/jailed) – asvd

0

У вас есть два основных варианта:

а) Укажите свой собственный язык, на котором вы полностью контролировать то, что сделано, так что ничего плохого не может случиться,

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

Моя проблема с б) довольно сложно разобраться во всех плохих вещах, которые кто-то может делать неясными способами.

Я предпочитаю a), потому что вам нужно только дать им возможность делать то, что вы позволяете.

Если у вас довольно простой набор формул, которые вы хотите обработать, на самом деле довольно легко написать анализатор/оценщик. См. Is there an alternative for flex/bison that is usable on 8-bit embedded systems?

Непонятно, что у вас проблемы с производительностью. да, вы хотите выполнить что-то 450 раз; но он включает в себя доступ к базам данных, стоимость которых будет доминировать над любыми вычислениями, включающими 1000 арифметических шагов. Вы можете обнаружить, что ваша скорость ограничена доступом к БД, который вам необходим для кэширования доступа к БД, чтобы ускорить его работу.