JavaScript для оценки простой математической строки, такой как 5 * 1.2 (eval / white-list?) - PullRequest
4 голосов
/ 28 марта 2012

У меня есть входной обмен, который преобразует числа вроде 05008 в 5,008.00.

Я рассматриваю вопрос об этом, чтобы сделать простые вычисления. Например, 45*5 будет автоматически преобразовано в 225.00.

Я мог бы использовать белый список символов ()+/*-0123456789., а затем передать результат в eval, я думаю, что эти символы безопасны для предотвращения любых опасных инъекций. Это предполагает, что я использую соответствующий try / catch, потому что может возникнуть синтаксическая ошибка.

  • Это белый список ОК, а затем передать его на eval?

  • Рекомендовать пересмотренный белый список

  • Вы рекомендуете другой подход (возможно, уже есть функция, которая делает это)

    Я бы предпочел, чтобы он был легким. Вот почему мне нравится подход eval / white-list. Очень маленький код.

Что вы рекомендуете?

Ответы [ 3 ]

3 голосов
/ 31 марта 2012

Этот белый список выглядит безопасным для меня, но это не такой простой вопрос.Например, в некоторых браузерах eval-строка, подобная этой:

/.(.)/(34)

, эквивалентна этой:

new RegExp('.(.)').exec('34')

и поэтому возвращает массив ['34','4'].Это "безопасно"?

Таким образом, хотя подход, вероятно, может быть сделан для безопасной работы, это может быть очень сложное предложение.Если вы продолжите эту идею, я думаю, что вы должны использовать намного более агрессивный подход для проверки ваших входных данных.Ваш принцип должен звучать так: «это член четко определенного набора строк, который, как известно, является« безопасным »», а не «это член плохо определенного набора строк, который исключает все строки, которые, как известно, являются« небезопасными ».«».Кроме того, чтобы избежать какого-либо риска заглядывания операторов, которые вы не рассмотрели (например, ++ или += или еще много чего), я думаю, вам следует вставить пробел перед каждым символом, не состоящим из цифр и без точек;и чтобы избежать риска, что скобки вызовут вызов функции, я думаю, что вам следует обрабатывать их самостоятельно, многократно заменяя (...) пробелом плюс результат вычисления ... (после подтверждения того, что результатом является число) плюс пробел.

(Кстати, а почему = в вашем белом списке? Я просто не могу понять, для чего это полезно!)

2 голосов
/ 31 марта 2012

Учитывая этот крайне ограниченный белый список, я не вижу никакого способа выполнить вредоносное действие, кроме как создать исключение.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * *] * * * * * * * * * *]] * * * * * * * * * *} * *}}}}}}}}}}}}}и выбросить что-нибудь еще.Таким образом, потенциально злонамеренный код в ссылке никогда не попадет на eval.

Это только оставляет возможность пользователю вводить что-то вредоносное в поле, но зачем даже беспокоиться об этом?Пользователь уже имеет доступ к консоли (Dev Tools), которую он может использовать для выполнения произвольного кода.

0 голосов
/ 01 апреля 2012

Часто упускаемая проблема с eval заключается в том, что он вызывает проблемы для минификаторов javascript.

Некоторые минификаторы, такие как YUI, выбирают безопасный маршрут и останавливают переименование переменных, как только видят оператор eval.Это означает, что ваш javascript будет работать, но ваш сжатый файл будет больше, чем нужно.

Другие, такие как Google Closure Compiler, будут продолжать переименовывать переменные, но если вы не будете осторожны, они могут нарушить ваш код.Вы должны избегать передачи строк с именами переменных в них eval.так например.

var input = "1+2*3";

var result = eval("input"); // unsafe

var result = eval(input); // safe
...