Почему Eval-подобные функции считаются злом, в отличие от других, возможно, вредных функций?


51

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

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

  • Пользовательские правила доступа к программным элементам (IIRC OpenERP имеет объект, ir.ruleкоторый может использовать динамический код Python).
  • Пользовательские вычисления и / или критерии (OpenERP имеет такие поля, чтобы разрешить пользовательские вычисления кода).
  • Парсеры отчетов OpenERP (да, я знаю, я волнуюсь из-за материала OpenERP ... но это основной пример, который у меня есть).
  • Кодирование эффектов заклинаний в некоторых ролевых играх.

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

Тем не менее, Eval является злом в массовой культуре. Такие вещи, как проникновение в вашу систему, приходят на ум.

Однако существуют и другие функции, которые могут быть вредными, если пользователи каким-либо образом к ним обращаются: отсоединение, чтение, запись (семантика файла), распределение памяти и арифметика указателей, доступ к модели базы данных (даже если не учитывать случаи инъекции SQL).

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

Но есть что-то особенное с evalфункциями (независимо от языка).

Вопрос : Есть ли исторический факт, что этот страх становится частью популярной культуры вместо того, чтобы уделять такое же внимание другим, возможно, опасным чертам?


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

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

13
Почему это стало частью популярной культуры, с большим вниманием, чем другие опасные черты? Потому что аллитерация eval - зло легко запомнить
Bergi

5
Распределение памяти и арифметические операции над указателями будут рассматриваться как зло, многие.
user253751

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 - это программа, которая позволяет мне - ее пользователю - выполнять произвольный ввод. Я считаю это полезным, а не плохим.
Den

3
@ Это было бы исключением. Будучи IDE, я уверен, что вы могли бы вызвать хаос без этой способности. Просто напишите это в своем исходном коде. Кроме того, у вас уже есть полный доступ к компьютеру, на котором он работает. Подразумевается, что это evalможет повысить привилегии. что не проблема, если они уже повышены.

3
@Den: Это то, что Раймонд Чен назвал «другой стороной шлюза». Вы уже можете запустить rm -rf /, нет необходимости делать это сложным образом через IDE. Проблема в evalтом, что она открывает эту способность для многих актеров, у которых не должно быть этой способности.
MSalters

38

Отчасти это просто, что нюанс сложен. Легко сказать, что никогда не использовать goto, открытые поля, интерполяцию строк для SQL-запросов или eval. Эти утверждения не следует понимать как говорящие о том, что никогда и ни при каких обстоятельствах нет причин использовать их. Но избегать их как общее правило - хорошая идея.

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 имеет смысл, и вы должны его использовать, но, очевидно, будьте осторожны с подводными камнями.


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

@JohnuaTaylor Вы имеете в виду третью причину, а не вторую?
user253751

1
@immibis, я думаю, он ссылается на код по второй причине. Но вы правы, это действительно связано с третьей причиной: производительность.
Уинстон Эверт

Видел этот вопрос , не так ли? ;)
jpmc26

@ jpmc26, нет. Но я видел много таких.
Уинстон Эверт

20

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

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


2
Ради аргумента, неправильное использование указателей также приводит к выполнению произвольного кода , но указатели не одобряются eval.
Дмитрий Григорьев

12
@DmitryGrigoryev Они действительно? За пределами C ++ указатели обычно считаются чрезвычайно опасными и их следует избегать. C # поддерживает указатели, например, но это, как правило, последнее, что вы пытаетесь после того, как исчерпали все другие опции (обычно, из соображений производительности при манипулировании данными). Большинство современных языков не поддерживают указатели. Даже сам C ++ движется в сторону «более безопасных» указателей, которые пытаются облегчить проблемы с произвольными указателями (например, используя истинные списки / массивы вместо просто указателей, используя safe_ptr, передачу ссылок ...).
Луаан

2
@DmitryGrigoryev: Можете ли вы дать ссылку для любого, кто говорит, что указатели менее опасны, чем Eval?
JacquesB

2
@JacquesB вот, пожалуйста :)
Дмитрий Григорьев,

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

15

Есть практическая и теоретическая причина.

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

Более теоретическая причина в том, что если сложно написать хороший код, то еще сложнее написать код, который пишет хороший код. Используете ли вы eval, или генерируете операторы SQL, склеивая строки, или пишете JIT-компилятор, то, что вы пытаетесь сделать, зачастую сложнее, чем вы ожидаете. Потенциальная возможность внедрения вредоносного кода - одна большая часть проблемы, но, кроме того, как правило, сложнее узнать правильный код, если он вообще не существует до времени выполнения. Таким образом, упрощенный совет состоит в том, чтобы вам было проще: «используйте параметризованные запросы SQL», «не используйте eval».

Возьмем ваш пример эффектов заклинаний: одно дело встроить компилятор или интерпретатор Lua в вашу игру, чтобы позволить игровым дизайнерам более простой язык, чем C ++ (или любой другой), для описания эффектов заклинаний. Большинство «проблем eval» не применимы, если все, что вы делаете, - это оценка кода, который был написан и протестирован и включен в игру, DLC или что-то еще. Это просто смешение языков. Большие проблемы возникают у вас, когда вы пытаетесь сгенерировать Lua (или C ++, или SQL, или команды оболочки, или что-то еще) на лету и все испортить.


1
Конечно, генерация кода во время выполнения может быть выполнена правильно, и eval может быть полезен. Например, я часто использую eval для метапрограммирования / макроподобных вещей, особенно когда я хочу большей производительности, чем может обеспечить «более чистый» ООП или функциональное решение. Результирующий код часто лучше и проще, потому что в нем меньше шаблонов. Тем не менее, знание различных проблем, связанных с изолированной программной средой, механизмами обхода, внедрением кода, правилами определения области действия, сообщениями об ошибках, оптимизацией и т. Д., Требует нетривиального уровня владения языком, и eval положительно опасен без этих знаний.
Амон

11

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

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

С помощью eval они могут взломать пятиугольник и сделать так, как будто вы это сделали. Они могут проверять нажатия клавиш, чтобы получить ваши пароли. Предполагая полный язык Тьюринга, они могут буквально делать все, что способен ваш компьютер.

И вы не можете подтвердить ввод. Это произвольная строка произвольной формы. Единственный способ проверить это - создать анализатор и механизм анализа кода для данного языка. Желаем удачи в этом.


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

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

3
@immibis - потому что никто никогда не взламывает игровые файлы ...
Telastyn

2
... это не то, что означает "завершить по Тьюрингу" (завершенность по Тьюрингу находится в одном шаге от неуместных вычислений до реальных вычислений).
Леушенко

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

6

Я думаю, что это сводится к следующим аспектам:

  • Необходимость
  • (Охраняемый) Использование
  • Доступ
  • проверяемость
  • Многоступенчатые атаки

Необходимость

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

(потом)

Спасибо за покупку. Как видите, все работает именно так, как я и обещал. О, вы хотите открыть изображение? Нет, ты не можешь. Я не буду использовать readметод, поскольку он несколько небезопасен. Сохранение? Нет, я не буду использовать write.

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

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

(Охраняемый) Использование

Многие методы могут быть потенциально опасными. Как, например, readи write. Типичным примером является веб-сервис, позволяющий читать изображения из определенного каталога, указав имя. Однако «имя» на самом деле может быть любым допустимым (относительным) путем в системе, что позволяет вам читать все файлы, к которым имеет доступ веб-служба, а не только изображения. Злоупотребление этим простым примером называется «обход пути». Если ваше приложение разрешает обход пути, это плохо. А readбез защиты от прохождения пути вполне можно назвать злом.

Однако в других случаях строка для readполностью находится под контролем программистов (может быть, жестко закодирована?). В этом случае это вряд ли зло, чтобы использовать read.

Доступ

Теперь еще один простой пример использования eval.

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

(То есть, пока вы не уволили этого милого администратора, но забыли отозвать его доступ. Теперь ваше веб-приложение уничтожено).

Проверяемость.

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

Используя пользовательский ввод в вызове чтения? Просто убедитесь (очень), что входные данные для вызова read не содержат ничего вредоносного. Нормализуйте путь и убедитесь, что открываемый файл находится в вашем медиа-каталоге. Теперь это безопасно.

Пользовательский ввод при записи вызова? Такой же!

SQL-инъекция? Просто избегайте его или используйте параметризованные запросы, и вы в безопасности.

Eval? Как вы собираетесь проверить ввод, который используется для evalвызова? Вы можете работать очень усердно, но действительно очень сложно (если не невозможно) заставить его работать надежно.

Многоступенчатые атаки

Теперь, каждый раз, когда вы используете пользовательский ввод, вам нужно взвесить преимущества его использования против опасностей. Защищайте его использование как можно больше.

Рассмотрим еще раз evalспособные вещи в примере администратора. Я сказал вам, что все в порядке.

Теперь учтите, что на самом деле в вашем веб-приложении есть место, где вы забыли скрыть пользовательский контент (HTML, XSS). Это меньшее преступление, чем доступный пользователю eval. Но, используя неэкранированный пользовательский контент, пользователь может получить evalдоступ к веб-браузеру администратора и добавить способный большой двоичный объект через сеанс администратора, предоставляя снова полный доступ к системе.

(Та же самая многоэтапная атака может быть сделана с помощью SQL-инъекции вместо XSS, или некоторые произвольные файловые записи заменяют исполняемый код вместо использования eval)


2
«Вы можете работать очень усердно, но действительно очень сложно (если не невозможно) заставить работать надежно». - Это является невозможным. Простое доказательство: вместо того , чтобы пытаться выяснить , является ли код пользователя при условии , является «обеспечить», просто пытаюсь выяснить что - то много, гораздо проще, и посмотреть , насколько сильно , что уже: делает код , предоставленный пользователем остановки?
Йорг Миттаг

2
@ JörgWMittag: дай мне программу, написанную на Coq, и я докажу это.
Андре Парамес

1
@ JörgWMittag: Согласен. В зависимости от языка и объема ввода пользователя. С таким же успехом может быть eval("hard coded string" + user_input_which_should_be_alphanumeric + "remainder"). Проверка того, что ввод является буквенно-цифровым, возможна. Кроме того, «делает ли это остановкой» ортогонально «делает ли он изменение / доступ к состоянию, к которому он не должен прикасаться» и «выполняет ли он методы, которые он не должен вызывать».
Sjoerd Job Postmus

3
@ JörgWMittag Невозможно доказать, что данная программа не будет что-то делать, но нет ничего невозможного консервативно определить ограниченный набор программ, для которых вы можете это доказать, и обеспечить, чтобы входные программы были членами этого набора.
user253751

3

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

Для интерпретируемых языков я могу просто использовать состояние интерпретатора, что легко, но в сочетании с JIT-компиляторами это все еще значительно увеличивает сложность.

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

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

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


«Чтобы эта функция работала вообще, это означает, что мне нужно держать слой отражения вокруг, который обеспечивает полный доступ ко всему внутреннему состоянию программы» - нет, только к тем частям, на которые вы хотите повлиять. В случае OpenERP / Odoo, уклоняемый код имеет доступ только к очень ограниченному числу переменных и функций, которые он может вызвать, и все они являются локальными по отношению к потокам.
Андре Парамес

1

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

Но это evalможет быть более известная уязвимость по той простой причине, что она поддерживается JavaScript. JavaScript является изолированным языком без прямого доступа к памяти или файловой системе, поэтому у него просто нет этих уязвимостей, за исключением слабых мест в самой реализации языка. Evalпоэтому является одной из самых опасных функций языка, так как открывает возможность произвольного выполнения кода. Я считаю, что на JavaScript разрабатывается гораздо больше разработчиков, чем на C / C ++, поэтому evalдля большинства разработчиков просто важнее знать об этом, чем переполнение буфера.


0

Ни один серьезный программист не посчитал бы, что Eval - «зло». Это просто инструмент программирования, как и любой другой. Страх (если есть страх) этой функции не имеет ничего общего с массовой культурой. Это просто опасная команда, которая часто используется неправильно и может привести к серьезным пробелам в безопасности и ухудшить производительность. Исходя из собственного опыта, я бы сказал, что редко встречается проблема программирования, которая не может быть решена более безопасно и эффективно другими способами. Программисты, которые чаще всего используют eval, - это те, кто, вероятно, менее квалифицирован, чтобы делать это безопасно.

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


это даже не пытается ответить на заданный вопрос: «Есть ли исторический факт для того, чтобы этот страх стал частью популярной культуры». Смотрите, как ответить
gnat

Вопрос, на мой взгляд, основан на ложной предпосылке, поэтому я ответил на нее как таковой.
user1751825

0

Я думаю, что вы достаточно хорошо освещаете это в следующей части вашего вопроса (выделение мое):

они имеют хорошее применение, если они используются правильно

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

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

Что касается исторического аспекта этого факта, evalфункции типов по существу позволяют выполнять произвольный код, который ранее использовался в популярной веб-CMS, Joomla! , С Joomla! поддержка более 2,5 миллионов сайтов по всему миру - это большой потенциальный ущерб не только посетителям этих сайтов, но и потенциально инфраструктуре, на которой он размещен, а также репутации сайтов / компаний, которые были использованы.

Joomla! Пример может быть простым, но он был записан.


0

Есть несколько веских причин препятствовать использованию eval(хотя некоторые специфичны для определенных языков).

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

Лично я бы не стал даже говорить, что это зло, но я всегда буду оспаривать использование evalв обзоре кода с формулировками в духе «Вы рассматривали какой-то код здесь ?» (если у меня будет время сделать хотя бы предварительную замену), или "вы уверены, что eval действительно является лучшим решением здесь?" (если я не сделаю).


это даже не пытается ответить на заданный вопрос: «Есть ли исторический факт для того, чтобы этот страх стал частью популярной культуры». См. Как ответить
комнат

0

В главе 6.4 « Общества разума Мински» он говорит:

У ума есть один способ наблюдать за собой и при этом следить за тем, что происходит. Разделите мозг на две части, A и B. Соедините входы и выходы A-мозга с реальным миром, чтобы он мог чувствовать, что там происходит. Но вообще не соединяйте B-мозг с внешним миром; вместо этого соедините его так, чтобы мозг А был миром мозга!

Когда одна программа (B) пишет другую программу (A), она функционирует как метапрограмма. Предмет B - программа A.

Есть программа на Си. Это тот, кто в вашей голове пишет программу B.

Опасность в том, что может быть кто-то (C ') со злым умыслом, который может вмешиваться в этот процесс, поэтому вы получаете такие вещи, как SQL-инъекция.

Задача состоит в том, чтобы сделать программное обеспечение умнее, не делая его еще более опасным.


Два отрицательных голоса и два отрицательных. Похоже, что это бьет по нервам.
Майк Данлавей

0

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.