Безопасно ли использовать eval () для данных ТОЛЬКО на стороне сервера? (и если нет, альтернативы, пожалуйста) - PullRequest
2 голосов
/ 18 июля 2011

Я создаю веб-сайт, где я делаю ajax-запросы для загрузки динамического контента ПОСЛЕ того, как я загружаю статическую страницу контейнера.По сути, мне нужно передать массив целых чисел на страницу с сервера, и я использую jQuery для загрузки данных.Я пишу целые внутри тега с известным именем и использую eval для чтения данных из него.Вот пример тега (возвращается из ajax):

<span runat="server" class="hidden" id="PhotoList" /> с codebehind list.ForEach(p => { sb.Append(p.ID.ToString() + ","); } );, где sb является StringBuilder, поэтому сервер в результате возвращает что-то вроде:

<span runat="server" class="hidden" id="PhotoList">1,4,5,42,9</span>

У меня есть переменная photoList, объявленная в javascript, и я звоню var scriptToEval = "photoList = [" + $("#PhotoList").html() + "];";

eval(scriptToEval);

Я не мастер Javascript, и я просто хочучтобы быть уверенным, что это безопасно, так как есть много дискуссий о том, является ли eval безопасным или нет.Я думаю, что это безопасно (я вставил весь код, который я использую с eval), но я, возможно, упустил момент, поэтому для меня важно мнение профессионала.Я знаю, почему они говорят, что eval опасен, поскольку он способен интерпретировать любой код, злонамеренный или нет, но здесь, я думаю, этот путь вообще не может быть скомпрометирован, так как ответ от сервера полностью находится под моим контролем.Другим вариантом было бы сделать ДРУГОЙ вызов ajax для переменных и загрузить их напрямую без ajax из возвращенного массива, но это суммировалось бы до двух вызовов (я все равно уже сделал вызов load, так как он действительно загружает некоторый HTML-контент с сервера), нотаким образом, хотя это немного странно (помещение переменных в скрытый тег HTML), это кажется удобным (в конце концов, ASP.NET также делает это и для viewstate!).

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

Ответы [ 5 ]

5 голосов
/ 18 июля 2011

Если вы можете быть уверены, что данные в безопасности, то eval() будет достаточно безвредным.

Если вы не уверены, вы можете использовать JSON.parse(), чтобы позаботиться об этом:

var arr = JSON.parse( "[" + $("#PhotoList").html() + "]" );

Для браузеров, которые не поддерживают JSON, вы можете включить библиотеку json2 .


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

var arr = $("#PhotoList").html().split(',');

for( var i = 0, len = arr.length; i < len; i++ ) {
    arr[i] = parseInt( arr[i], 10 );
}

РЕДАКТИРОВАТЬ: Поскольку вы используете jQuery, если по какой-то причине вы действительно не хотите .eval(), затем используйте метод jQuery.parseJSON() [документы] .

var arr = jQuery.parseJSON("[" + $("#PhotoList").html() + "]");

РЕДАКТИРОВАТЬ 2: Другой способ сделать это - использовать .replace(), передав функцию в качестве значения замены.Это позаботится об итерации для вас.

var arr = [];

$("#PhotoList").html().replace(/\d+/g, function( s ) { arr.push( parseInt(s,10) ); });

... так много способов сделать это.

2 голосов
/ 18 июля 2011

Конечно, это не безопасно. Остановить код с помощью отладчика довольно просто и изменить содержимое элемента или переменных, которые использует скрипт.

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

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

1 голос
/ 18 июля 2011

Безопасно, да, если ваш сервер безопасен.Как правило, единственное время, когда вы действительно хотите избегать использования eval(), - это когда пользователи могут добавлять код, который могут видеть другие пользователи.Как будто вы никогда не захотите использовать eval() при отображении сообщения на форуме и т. Д. Если код поступает с вашего сервера или если пользовательский ввод отображается только для самого себя, eval() подойдет.По сути, это то, что jsfiddle делает.

0 голосов
/ 18 июля 2011

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

Также возможно сделать то, что вы хотите без eval:

1 - для установки глобальногопеременная, вместо использования eval вы можете использовать объект глобальной области видимости.Все следующие условия эквивалентны, если myList является глобальной переменной:

myList = [1,2,3];
window.myList = [1,2,3];
window['myList'] = [1,2,3];

2 - Для получения элементов массива вы можете использовать метод .split() из строк:

node.innerHTML.split(',')

3 - Если вы хотите преобразовать строку в число, одним из простых способов является использование унарного оператора +:

+"3" // is the number 3
0 голосов
/ 18 июля 2011

Код

var result = eval(code);

Может меняться с

var result = new Function('return '+code+');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...