Кращі практики для виконання ненадійного коду


31

У мене є проект, де мені потрібно дозволити користувачам запускати до мого сервера довільний ненадійний код python ( трохи подібний ). Я досить новачок у python, і я хотів би уникати помилок, які вводять в систему дірки в безпеці чи інші вразливості. Чи є доступні найкращі практики, рекомендовані читання чи інші вказівки, які ви можете дати мені, щоб зробити мою послугу корисною, але не зловживаною?

Ось що я вважав досі:

  • Видаліть __builtins__із execконтексту, щоб заборонити використання потенційно небезпечних пакетів, таких як os. Користувачі зможуть користуватися лише пакетами, які я їм надаю.
  • Використовуйте нитки, щоб застосувати розумний час очікування.
  • Я хотів би обмежити загальний об'єм пам'яті, який можна виділити в execконтексті, але я не впевнений, чи це можливо.

Є кілька альтернатив прямому exec, але я не впевнений, яка з них була б корисною тут:

  • Використання символу ast.NodeVisitorдля лову будь-якої спроби доступу до небезпечних об'єктів. Але які об’єкти слід заборонити?
  • Пошук будь-яких подвійних підкреслень на вході. (менш витончена, ніж наведений вище варіант).
  • Використання PyPyабо щось подібне до пісочниці коду.

ПРИМІТКА. Мені відомо, що існує принаймні один інтерпретатор на основі JavaScript. Це не спрацює за моїм сценарієм.



3
@MartijnPieters: Відмінно. Мабуть, гідна відповіді, якщо підсумувати кожну.
Роберт Харві

Також врахуйте: сміття, залишене на диску, мережа (не дозволяйте їм надсилати спам чи інше), дозволи на інші файли (читання ваших файлів). Навіть витягнути, поки цикл може зруйнувати механіку компакт-дисків ... Я б пішов на віртуалізацію (в'язниці чи якийсь кінометраж, який ви її назвали) або, принаймні, користувач майже не має привілеїв. Встановіть розумний приємний і об'єм пам'яті, щоб скористатися своїми програмами.
kyticka


1
Спробуйте PyPy :> Sandboxing: PyPy надає можливість запускати ненадійний код повністю захищеним способом.
Ворак

Відповіді:


28

Пітонних пісочниць важко . Python за своєю суттю є інтроспективним, на різних рівнях.

Це також означає, що ви можете знайти заводські методи для конкретних типів із самих цих типів та сконструювати нові низькорівневі об'єкти, які будуть запускатись безпосередньо інтерпретатором без обмежень.

Ось кілька прикладів пошуку творчих способів вирватися з пісочниць Python:

Основна ідея - завжди знайти спосіб створити базові типи Python; функції та класи та вириваються з оболонки, отримуючи інтерпретатор Python для виконання довільного (неперевіреного!) байтового коду.

Те саме і більше стосується execтвердження ( exec()функція в Python 3).

Отже, ви хочете:

  • Суворо контролюйте компіляцію байтів коду Python або принаймні післяобробляйте байт-код, щоб видалити будь-який доступ до імен, починаючи з підкреслення.

    Для цього потрібні глибокі знання про те, як працює інтерпретатор Python та як структурований байт-код Python. Об'єкти коду вкладені; байт-код модуля охоплює лише вищий рівень висловлювань, кожна функція та клас складаються з власної послідовності байтових кодів плюс метаданих, що містять, наприклад, інші об'єкти байт-кодів для вкладених функцій та класів.

  • Потрібно використовувати білі списки модулів, якими можна користуватися. Обережно.

    Модуль python містить посилання на інші модулі. Якщо ви імпортуєте os, osу просторі імен вашого модуля є локальне ім'я, яке посилається на osмодуль. Це може призвести рішучого зловмисника до модулів, які можуть допомогти їм вирватися з пісочної скриньки. Наприклад, pickleмодуль дозволяє завантажувати довільні кодові об'єкти, наприклад, якщо будь-який шлях через білі модулі веде до pickleмодуля, у вас все ще виникає проблема.

  • Потрібно суворо обмежити часові квоти. Навіть найнейтралізований код все одно може намагатися запуститись назавжди, пов'язуючи свої ресурси.

Погляньте на RestrictedPython , який намагається надати вам суворий контроль над байт-кодом. RestrictedPythonперетворює код Python в те, що дозволяє контролювати, які імена, модулі та об'єкти допустимі в Python 2.3 до 2.7.

Якщо RestrictedPythonця безпека є достатньою для ваших цілей, залежить від політики, яку ви здійснюєте. Не допускати доступу до імен, що починаються з підкреслення і суворо білими модулями, буде початком.

На мою думку, єдиний справді надійний варіант - це використовувати окрему Віртуальну машину, без доступу до мережі до зовнішнього світу, яку ви знищуєте після кожного запуску. Кожному новому сценарію замість нього надається новий VM. Таким чином, навіть якщо коду вдасться вирватися з вашої пісочної скриньки Python (що малоймовірно), весь зловмисник отримує доступ до нетривалого та без значення.


10

TL; DR Використовуйте chroot / jail та запускайте як користувацького користувача без будь-яких пільг.

Найкраща практика для виконання ненадійного коду - це відокремлення його через системну пісочну скриньку. Для найбільшої безпеки:

  • створити контейнер тільки з Python, і це залежності та залежності контейнера
  • створити контейнер без усіх необхідних пристроїв (тобто мережі та пам’яті)
  • створити контейнер з обмеженнями на пам'ять та використання процесів
  • відтворити контейнер з кожним запуском (або принаймні з кожним унікальним користувачем та максимальним періодом часу)
  • запускатись як користувач з найменшими необхідними привілеями
  • запуститись як користувач, який не має дозволу на запис файлів

Ви також дотримуєтесь стандартних практик безпечного ведення речей у chroot. Ви можете відновити файлову систему chroot з кожним викликом, а також особливо параноїчно. Зазвичай ви просто робите користувач не в змозі вносити зміни до файлової системи, в якій працює chroot.


Це єдине, де ви навіть віддалено будете впевнені, що правильно це зробили - дайте йому це власний процес.
Майкл Коне

3

Ви не можете зробити це безпечно.

Якщо ви хотіли зробити щось подібне безпечно, вам слід почати з власної реалізації python, який працює в повністю контрольованому середовищі, бажано працює в браузері користувачів, а не у вашій системі. Ви можете почати з Jython (python for java) і упакувати його як аплет java. Оскільки він працюватиме в пісочниці Java на машині користувача, ваша система буде досить безпечною.


4
Питання безпеки було для його сервера, а не для машини клієнта. Потенційні небезпеки безпеки Java, як і для будь-яких інших веб-технологій, полягають у тому, що сервер може використовуватися для розгортання небезпечних для клієнта програм.
ddyer

1
@grasGendarme так само, як нові штрихи про авіакатастрофи насправді багато розповідають про те, наскільки вони рідкісні; історії про отвори в безпеці Java говорять про те, що java порівняно безпечна. Ви ніколи не отримаєте таку історію про С, оскільки відповідь, яку ви отримаєте, була б "ну так; якщо ви запустите її, вона зробить все, що завгодно"
Річард Тінгл

2

Як Мартийн говорив вище, в Python це дійсно дуже важко. Відверто, оскільки Python настільки інтроспективний, я не думаю, що це можливо через обмеження мовних особливостей. І якщо ви отримаєте пісочницю, яка працює для однієї версії Python, є ймовірність, що наступна версія зламає її.

Я б подивився на PyPy замість стандартного CPython. Словом, це сумісна альтернативна реалізація Python. Він має кілька переваг та відмінних особливостей, і одна з них - це пісочниця за допомогою заміни системних викликів замість обмеження мовних функцій.


0

Поки продуктивність не є важливою для вас, ви завжди можете запускати її в Brython, що ефективно розміщує її в пісочниці JavaScript

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.