Чому риси, подібні до овалів, вважаються злими, на відміну від інших, можливо, шкідливих рис?


51

Більшість сучасних мов (які так чи інакше трактуються) виконують якусь функцію eval . Така функція виконує довільний код мови, більшу частину часу проходить як основний аргумент у вигляді рядка (різні мови можуть додавати більше функцій функції eval).

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

  • Спеціальні правила доступу до програмних елементів (IIRC OpenERP має об'єкт, ir.ruleякий може використовувати динамічний код пітона).
  • Спеціальні обчислення та / або критерії (OpenERP має такі поля, щоб дозволити розрахунки спеціального коду).
  • Аналізатори звітів OpenERP (так, я знаю, що я змушую вас з речами OpenERP ... але це головний приклад, який я маю).
  • Кодування ефектів заклинання в деяких іграх RPG.

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

Однак евал є злом у популярній культурі. Такі речі, як проникнення у вашу систему, приходять в голову.

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

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

Але є щось особливе з evalфункціями (незалежно від мови).

Питання : Чи є якийсь історичний факт, що цей страх стає частиною популярної культури, замість того, щоб приділяти однакову увагу іншим, можливо, небезпечним рисам?


11
Я не погоджуюся з тим, що це занадто широко, і як доказ я представляю чотири відповіді, які мають розумну тривалість.

12
Вони проголосували за закриття як занадто широке ? (Я ще не бачу близьких голосів у цій спільноті) Ця близька причина стає неповноцінною причиною, яка зовсім не має сенсу. Особливо, коли питання, яке я запитую, є цілком зрозумілим із прикладами та конкретним питанням. Я запитаю цю тему в Мета ...
Луїс Масуеллі

13
Чому воно стає частиною популярної культури, приділяючи більше уваги, ніж інші небезпечні риси? Оскільки алітерація eval - зло легко запам’ятати
Бергі

5
Розподіл пам’яті та арифметика вказівників багато хто сприймає як зло.
користувач253751

5
Слід зазначити, що OpenERP (зараз Odoo) не просто викликає eval, він має внутрішню функцію, яка називається, safe_evalяка готує середовище для запобігання дії коду небезпечних речей. Проте виявлено помилок, оскільки Python є досить гнучкою мовою, і тому її важко контролювати.
Андре Парамеш

Відповіді:


76

evalФункція сама по собі не є злом, і є тонкий момент , який я не вірю , що ви робите:

Дозволити програмі виконувати довільний ввід користувача погано

Я написав код, який використовував evalтип функції, і він був захищеним: програма і параметри були жорстко закодовані. Іноді немає жодної функції мови чи бібліотеки, щоб виконати те, що потрібно програмі, і виконати команду оболонки - це короткий шлях. "Я повинен закінчити кодування за кілька годин, але написання Java / .NET / PHP / будь-якого коду займе два дні. Або я можу evalце за п'ять хвилин."

Після того, як ви дозволите користувачам виконувати все, що завгодно, навіть якщо це заблоковано за привілеєм користувача або за "захищеним" екраном, ви створюєте вектори атак. Щотижня деякі випадкові CMS, програмне забезпечення для ведення блогів тощо мають виправлену дірку безпеки, де зловмисник може експлуатувати подібну дірку. Ви покладаєтесь на весь стек програмного забезпечення для захисту доступу до функції, яка може бути використана rm -rf /або щось інше катастрофічне (зауважте: ця команда навряд чи вдасться, але вийде з ладу після нанесення невеликої шкоди).

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

Так, є історичний прецедент. Через численні помилки, які протягом багатьох років виправлялися в різних програмних засобах, які дозволяють віддаленим зловмисникам виконувати довільний код, ідея evalздебільшого не вийшла з ладу. Сучасні мови та бібліотеки мають багатий набір функціональних можливостей, які роблять evalменш важливими, і це не випадково. Це обоє спрощує використання функцій та зменшує ризик експлуатації.

Багато уваги приділялось багатьом потенційно небезпечним особливостям популярних мов. Якщо один отримує більше уваги, перш за все, залежить від точки зору, але evalособливість , безумовно , є доказову проблема безпеки , яка легко зрозуміти. Для одного вони дозволяють виконувати команди операційної системи, включаючи вбудовані оболонки та зовнішні програми, які є стандартними (наприклад, rmабо del). По-друге, у поєднанні з іншими подвигами зловмисник може мати можливість завантажити власний виконуваний сценарій або скрипт оболонки, а потім виконати його за допомогою свого програмного забезпечення, відкривши двері, щоб майже нічого не трапилося (нічого з цього не було).

Це складна проблема. Програмне забезпечення є складним, а стек програмного забезпечення (наприклад, LAMP ) - це кілька програм, які взаємодіють між собою складними способами. Будьте уважні, як ви використовуєте такі мовні функції, і ніколи не дозволяйте користувачам виконувати довільні команди.


2
Ви - той самий :). Хоча, якщо є добре відомий приклад, який сприяв цій культурі, я хотів би побачити це у відповіді.
Луїс Масуеллі

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

1
Мій IDE - це програма, яка дозволяє мені - користувачеві - виконувати довільні введення. Я вважаю це корисним, а не поганим.
День

3
@Den, це буде винятком. Будучи IDE, я впевнений, що ви можете викликати хаос без цієї можливості. Просто напишіть це у своєму вихідному коді. Також у вас вже є повний доступ до комп'ютера, на якому він працює. Звідси випливає, що особаeval може підвищувати привілеї. що не є проблемою, якщо вони вже підвищені.

3
@Den: Це те, що Реймонд Чен узагальнив як "іншу сторону повітряного блоку". Ви вже можете запустити rm -rf /, немає необхідності робити це складно через IDE. Проблема evalполягає в тому, що вона відкриває цю здатність багатьом акторам, які не повинні мати таку здатність.
MSalters

38

Частина просто в тому, що нюанс важкий. Легко сказати таку річ, як ніколи не використовувати goto, public поля, інтерполяцію рядків для запитів sql або eval. Ці твердження насправді не слід розуміти як такі, що говорять про те, що ніколи і за будь-яких обставин немає причин їх використовувати. Але уникати їх як загального правила - це гарна ідея.

Евал сильно не відштовхується, оскільки поєднує в собі кілька загальних питань.

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

По-друге, новачки, як правило, використовують eval, щоб обійти погано структурований код. Кодер для початківців може написати код, який виглядає так:

x0 = "hello"
x1 = "world"
x2 = "how"
x3 = "are"
x4 = "you?"
for index in range(5):
   print eval("x" + index)

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

По-третє, eval, як правило, неефективний. Багато зусиль витрачається на прискорення реалізації мов програмування. Але пришвидшити прискорення eval важко, і його використання, як правило, згубно вплине на вашу продуктивність.

Отже, eval - не зло. Можна сказати, що eval - це зло, адже добре, це привабливий спосіб його викласти. Будь-який початківець кодер повинен суворо триматися подалі від eval, оскільки все, що вони хочуть зробити, eval майже напевно неправильне рішення. Для певних випадків розширеного використання eval має сенс, і ви повинні використовувати його, але очевидно, будьте обережні до підводних каменів.


13
Ваша друга справа дуже важлива. У мовах, які мають eval, але також складені, оцінка рядка для створення змінної посилання нетривіальна. Наприклад, якщо var x = 3; print(x)буде зібрано , тобто не потрібно бути будь-який час виконання знання про те , що джерело використовував назву «х». Для того, var x = 3; print(eval("x"))щоб працювати, це картографування потрібно записати. Це справжнє питання: у Common Lisp (let ((x 3)) (print (eval 'x)))викинутиме виключення незв'язаної змінної, оскільки лексична змінна x не має жодного зв’язку з іменем після компіляції коду.
Джошуа Тейлор

@JohnuaTaylor Ви маєте на увазі третю причину, а не другу?
користувач253751

1
@immibis, я думаю, що він посилається на код з другої причини. Але ви праві, це дійсно стосується третьої причини: виконання.
Вінстон Еверт

Бачили це питання , чи не так? ;)
jpmc26

@ jpmc26, ні. Але я бачив багато подібного.
Вінстон Еверт

20

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

"Інші, можливо, шкідливі помилки" можуть мати обмеження, а це означає, що вони, за визначенням, здатні нанести менше шкоди, ніж використовувати довільне виконання коду.


2
Заради аргументів неправильне використання покажчиків також призводить до довільного виконання коду , але покажчики нахмурюються набагато менше, ніж evalє.
Дмитро Григор’єв

12
@DmitryGrigoryev Це насправді? Поза C ++, вказівники, як правило, вважаються надзвичайно небезпечними та їх уникають. Наприклад, C # підтримує покажчики, але це, як правило, останнє, що ви спробуєте після вичерпання всіх інших варіантів (як правило, з міркувань продуктивності маніпулювання даними). Більшість сучасних мов не підтримують покажчики. Навіть сам C ++ рухається до "безпечніших" покажчиків, які намагаються полегшити проблеми з довільними покажчиками (наприклад, використовуючи справжні списки / масиви замість просто покажчиків, використовуючи safe_ptr, передачу посилань ...).
Луань

2
@DmitryGrigoryev: Чи можете ви надати посилання для тих, хто говорить, що вказівники менш небезпечні, ніж eval?
ЖакБ


1
@JacquesB, так; це було задумано як жарт (я очікував, що посмішка дасть зрозуміти досить). ОП зробив це твердження, а не я, тому ви повинні попросити його підтвердити.
Дмитро Григор’єв

15

Є практична і теоретична причина.

Практична причина полягає в тому, що ми спостерігаємо, що це часто спричиняє проблеми. Рідко таке, що eval призводить до хорошого рішення, і це часто призводить до поганого рішення, де ви отримали б краще в кінцевому підсумку, якби ви робили вигляд, що eval не існує, і підходити до проблеми по-іншому. Тож спрощена порада - це ігнорувати її, і якщо ви зіткнетеся з випадком, коли ви хочете ігнорувати спрощену пораду, добре, сподіваємось, ви продумали її достатньо, щоб зрозуміти, чому спрощена порада не застосовується та поширена підводні камені не вплинуть на вас.

Більш теоретична причина полягає в тому, що якщо важко написати хороший код, ще складніше написати код, який пише хороший код. Незалежно від того, чи використовуєте ви eval, або генеруєте оператори SQL шляхом склеювання рядків або написання компілятора JIT, те, що ви намагаєтеся, часто складніше, ніж ви очікували. Потенціал введення зловмисного коду є однією з важливих частин проблеми, але окрім цього, як правило, важче знати правильність вашого коду, якщо ваш код навіть не існує до часу виконання. Отже, спрощена порада полягає в тому, щоб полегшити для себе речі: "використовувати параметризовані SQL-запити", "не використовувати eval".

Приклад прикладу ефектів правопису: одне - створити у вашій грі компілятор або інтерпретатор Lua (або що завгодно), щоб дозволити дизайнерам ігор легшою мовою, ніж C ++ (або будь-якій іншій) для опису ефектів правопису. Більшість "проблем eval" не застосовуються, якщо все, що ви робите, - це оцінювання коду, який був написаний і перевірений і включений у гру або в DLC або що у вас є. Це просто змішування мов. Великі проблеми стикаються з вами, коли ви намагаєтесь згенерувати Lua (або C ++, або SQL, або команди оболонки, або що завгодно), і зіпсувати це.


1
Звичайно, генерація коду виконання може бути виконана правильно, а eval може бути корисним. Наприклад, я часто використовую eval для метапрограмування / макроподібних речей, особливо тоді, коли я хочу отримати більш високу продуктивність, ніж «чистіший» OOP або функціональне рішення. Отриманий код часто кращий і простіший, тому що має менше котлових панелей. Однак, усвідомлення різних проблем, пов’язаних з пісочницею, механізмами виходу з ладу, введення коду, правила визначення обсягу, повідомлення про помилки, оптимізація тощо, вимагає нетривіального рівня володіння мовою, і без цих знань еваль позитивно небезпечний.
амон

11

Ні, очевидного історичного факту немає.

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

З eval вони можуть зламати п’ятикутник і зробити так, як ви це зробили. Вони можуть перевірити ваші натискання клавіш, щоб отримати ваші паролі. Якщо припустити повну мову Тюрінга, вони можуть буквально робити все, на що здатний ваш комп'ютер.

І ви не можете перевірити дані. Це довільна рядок вільної форми. Єдиний спосіб перевірити це - побудувати механізм аналізатора та аналізу коду для мови, про яку йде мова. Найкраща удача з цим.


1
... або мати вхід із надійного джерела, наприклад файлів визначення заклинань для гри.
користувач253751

3
@immibis, але якщо вхід заздалегідь визначений і перевірений безпечним, навіщо використовувати eval, коли він може бути включений у джерело системи?
Жуль

3
@immibis - тому що ніхто ніколи не зламає файли гри ...
Теластин

2
... це не те, що означає "Тьюрінг завершений" (повнота Тюрінга - це крок від нерелевантних до обчислень у реальному світі).
Левшенко

1
@Telastyn: Що програма Javascript не може зробити. Або навіть програму C ++. Javascript працює всередині пісочниці (браузера), яка знаходиться в іншій пісочниці (дзвінок 3 у розмові x86) Вектор переривання знаходиться поза тією пісочницею, під керуванням ОС. І ця зовнішня пісочниця, кільце 3, підтримується процесором.
MSalters

6

Я думаю, що це зводиться до таких аспектів:

  • Необхідність
  • (Охороняється) Використання
  • Доступ
  • Перевіреність
  • Багатоетапні атаки

Необхідність

Привіт, я написав цей надзвичайно класний інструмент для редагування зображень (доступний за $ 0,02). Після відкриття зображення ви можете пропустити безліч фільтрів над вашим зображенням. Ви навіть можете самим розписати сценарій за допомогою Python (програми, в якій я написав заявку). Я просто використаю evalваш внесок, довіряючи вам, що ви будете поважним користувачем.

(пізніше)

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

Я намагаюся сказати: читання / запис потрібно майже для основних інструментів. Те ж саме для зберігання високих балів вашої надзвичайної гри.

Без читання / запису ваш редактор зображень марний. Без eval? Я напишу вам користувацький плагін для цього!

(Охороняється) Використання

Дуже багато методів можуть бути небезпечними. Як, наприклад, readі write. Поширений приклад - веб-служба, що дозволяє читати зображення з певного каталогу, вказуючи ім'я. Однак "ім'ям" насправді може бути будь-який дійсний (відносний) шлях до системи, що дозволяє читати всі файли, до яких веб-служба має доступ, а не лише зображення. Зловживання цим простим прикладом називається "обхід шляху". Якщо ваш додаток дозволяє пройти шлях, це погано. readБез захисту від шляху для обходу може вей називатися злом.

Однак в інших випадках рядок for readповністю знаходиться під контролем програмістів (можливо, жорстко закодований?). У такому випадку це навряд чи зло read.

Доступ

Тепер ще один простий приклад, використовуючи eval.

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

(Тобто, поки ви не звільнили цього приємного адміністратора, але забули відкликати його доступ. Тепер ваш веб-додаток потрапив у сміття).

Перевіреність.

Ще один аспект, важливий, я думаю, - наскільки легко перевірити дані користувача.

Використання вводу користувача при читанні дзвінка? Просто переконайтеся, що вхід для читання дзвінка не містить нічого шкідливого. Нормалізуйте шлях, і перевірте, чи відкритий файл знаходиться у вашому медіа-каталозі. Тепер це безпечно.

Користувацький вхід під час запису? Те саме!

Введення SQL? Просто уникайте цього або використовуйте параметризовані запити, і ви в безпеці.

Евал? Як ви збираєтеся перевірити вхід, який використовується для evalдзвінка? Можна працювати дуже важко, але насправді дуже важко (якщо не неможливо) змусити її надійно працювати.

Багатоетапні атаки

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

Розглянемо ще раз evalздатний матеріал у прикладі адміністратора. Я сказав вам, що це було добре.

А тепер подумайте, що у вашому веб-додатку насправді є місце, де ви забули уникнути вмісту користувача (HTML, XSS). Це менше правопорушення, ніж доступний користувачеві eval. Але, використовуючи нерозміщений вміст користувача, користувач може перейняти веб-браузер адміністратора та додати evalможливість блобування через сеанс адміністратора, що дозволяє знову отримати повний доступ до системи.

(Таку ж багатоступеневу атаку можна зробити з ін'єкцією SQL замість XSS, або якийсь довільний файл записує заміною виконуваного коду замість використання eval)


2
"Ви можете працювати дуже важко, але це дійсно дуже важко (якщо не неможливо), щоб змусити його надійно працювати". - Це є неможливим. Просте доказ: замість того , щоб намагатися з'ясувати , є чи ні коду користувачеві надається «безпечний», просто намагаються з'ясувати що - то багато, набагато простіше, і подивитися , наскільки сильно , що вже: це код , наданий користувачем зупинки?
Йорг W Міттаг

2
@ JörgWMittag: дайте мені програму, написану на Coq, і я це доведе.
Андре Парамеш

1
@ JörgWMittag: Погоджено. Залежно від мови та обсягу введення користувача. Це теж могло бути eval("hard coded string" + user_input_which_should_be_alphanumeric + "remainder"). Перевірити, що введення є буквено-цифровим можливим. Крім того, "чи зупиняється" є ортогональним для "чи змінює стан / стан доступу, який він не повинен торкатися" та "чи це методи, які він не повинен викликати".
Джордж Постмус

3
@ JörgWMittag Неможливо довести, що дана програма нічого не зробить, але не неможливо консервативно визначити обмежений набір програм, для яких ви можете це довести, і застосувати, що програми введення є членами цього набору.
користувач253751

3

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

Для інтерпретованих мов я можу просто використовувати стан інтерпретатора, що легко, але в поєднанні з компіляторами JIT це все ще значно збільшує складність.

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

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

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


"Для того, щоб ця функція взагалі працювала, це означає, що мені потрібно тримати шар відбиття навколо, який забезпечує повний доступ до внутрішнього стану всієї програми" - ні, лише до частин, на які ви хочете вплинути. У випадку OpenERP / Odoo код, який вилучається, має лише обмежену кількість змінних та функцій, які він може викликати, і всі вони є локальними потоками.
Андре Парамеш

1

Я відкидаю припущення, яке evalвважається більш злим, ніж арифметичне вказівник або небезпечніше, ніж прямий доступ до пам'яті та файлової системи. Я не знаю жодного розумного розробника, який би в це повірив. Крім того, мови, що підтримують арифметичний / прямий доступ до пам'яті, зазвичай не підтримують, evalі навпаки, тому я зауважую, наскільки часто таке порівняння навіть було б доречним.

Але evalможе бути більш відома вразливість з тієї простої причини, що вона підтримується JavaScript. JavaScript - це пісочне середовище без прямої пам’яті чи доступу до файлової системи, тому просто не має цих вразливих місць, що забороняють слабкі місця у самій мовній реалізації. EvalТому є однією з найнебезпечніших особливостей мови, оскільки вона відкриває можливість довільного виконання коду. Я вважаю, що набагато більше розробників розробляється в JavaScript, ніж у C / C ++, тому evalпросто важливіше знати, ніж переповнення буфера для більшості розробників.


0

Жоден серйозний програміст не вважав би Евала "Злом". Це просто інструмент програмування, як і будь-який інший. Страх (якщо є страх) цієї функції не має нічого спільного з популярною культурою. Це просто небезпечна команда, яку часто зловживають, і може ввести серйозні отвори в безпеці та погіршити продуктивність. З власного досвіду я б сказав, що рідко трапляється проблема програмування, яку не можна вирішити безпечніше та ефективніше іншими способами. Програмісти, які, швидше за все, використовують eval, - це ті, хто, мабуть, найменш кваліфікований, щоб зробити це безпечно.

Сказавши це, є мови, де використання eval є доцільним. Перл приходить на думку. Однак особисто мені здається, що це дуже рідко потрібно в інших, більш сучасних мовах, які споконвічно підтримують структуровану обробку виключень.


це навіть не намагається вирішити поставлене питання: "Чи є якийсь історичний факт, щоб цей страх став частиною популярної культури". Дивіться, як відповісти
gnat

Питання, на мою думку, ґрунтується на помилковій передумові, тому я відповів на нього як такий.
користувач1751825

0

Я думаю, ви досить добре висвітлюєте це в наступній частині свого запитання (моє наголос):

вони добре використовують, якщо вони належним чином використовуються

Для 95%, які можуть правильно його використовувати, це все добре і добре; але завжди знайдуться люди, які не користуються ним належним чином. Деякі з них будуть недосвідчені та бракують здібностей, інші - зловмисні.

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

Що стосується його історичного факту, evalфункції типу дозволяють виконувати довільне виконання коду, який раніше використовувався в популярній веб-CMS, Joomla! . З Джомлою! що працює над 2,5 мільйонами сайтів у всьому світі , це багато потенційного шкоди не тільки відвідувачам цих сайтів, але й потенційно інфраструктурі, на якій він розміщений, а також репутації сайтів / компаній, які експлуатуються.

The Joomla! Приклад може бути простим, але він був записаний.


0

Є кілька вагомих причин відмовити в користуванні eval(хоча деякі специфічні для певних мов).

  • Навколишнє середовище (лексично та динамічно), яке використовується, evalчасто дивує (тобто, ти думаєш, eval(something here)потрібно робити одне, але це робить інше, можливо, викликаючи винятки)
  • Часто існує кращий спосіб здійснити те саме (об'єднання побудованих лексичних закриттів іноді є кращим рішенням, але це, можливо, є загальним для Lisp)
  • Нарешті занадто просто в кінцевому підсумку оцінювати небезпечні дані (хоча в основному це може бути захищено).

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


це навіть не намагається вирішити поставлене питання: "Чи є якийсь історичний факт, щоб цей страх став частиною популярної культури". Дивіться, як відповісти
gnat

0

У « Товаристві розуму Мінського» , глава 6.4, він говорить

Існує один спосіб розуму спостерігати за собою і все ще слідкувати за тим, що відбувається. Розділіть мозок на дві частини, A і B. Підключіть входи та виходи A-мозку до реального світу - щоб він міг відчути, що там відбувається. Але взагалі не підключайте B-мозок до зовнішнього світу; замість цього підключіть його, щоб A-мозок був світом B-мозку!

Коли одна програма (B) пише іншу програму (A), вона функціонує як метапрограма. Тема B - програма А.

Є програма С. Це той, який у вашій голові пише програму B.

Небезпека в тому, що може бути хтось (C ') зі злими намірами, хто може втручатися в цей процес, тож ви отримуєте такі речі, як SQL-ін'єкція.

Завдання полягає в тому, щоб зробити програмне забезпечення розумнішим, не роблячи його ще більш небезпечним.


Дві версії та два поточні права. Схоже, можливо, це забиває нерв.
Майк Данлаве

0

У вас є багато хороших відповідей, і головна причина полягає в тому, що довільне виконання коду є поганим mmmkay, але я додам ще один фактор, який інші торкнулися лише краю:

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

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