Должны ли методы jQuery parseJSON / getJSON использоваться? - PullRequest
5 голосов
/ 13 июля 2010

Я заметил, что jQuery parseJSON в основном выполняет простое регулярное выражение "check":

parseJSON: function( data ) {
    if ( typeof data !== "string" || !data ) {
        return null;
    }

    // Make sure leading/trailing whitespace is removed (IE can't handle it)
    data = jQuery.trim( data );

    // Make sure the incoming data is actual JSON
    // Logic borrowed from http://json.org/json2.js
    if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
        .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {

        // Try to use the native JSON parser first
        return window.JSON && window.JSON.parse ?
            window.JSON.parse( data ) :
            (new Function("return " + data))();

    } else {
        jQuery.error( "Invalid JSON: " + data );
    }
},

Если он проходит эту «проверку» и если это современный браузер, то используется собственный анализатор JSON. В противном случае я предполагаю, что для браузера, такого как IE6, автоматически вызывается новая функция, которая возвращает объект.

Вопрос № 1 : Поскольку это всего лишь простой тест на регулярные выражения, разве это не склонно к каким-то неявным эксплойтам с краями? Разве мы не должны использовать полноценный парсер для браузеров, которые не поддерживают хотя бы собственный анализ JSON?

Вопрос № 2 : Насколько «безопаснее» (new Function(" return " + data ))() по сравнению с eval("(" + text + ")")?

Ответы [ 2 ]

3 голосов
/ 13 июля 2010

Как уже упоминалось в комментариях, анализатор JSON jQuery «заимствует» логику, которая проверяет, является ли строка JSON действительной, прямо из json2.js. Это делает его «таким же безопасным», как и наиболее распространенная не нативная реализация, которая в любом случае довольно строгая:

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

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

На вопрос 2 очень хорошо ответил Бобинс в другом вопросе:

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

Зацените Ответ Ника Крейвера Там тоже есть прямая цитата Джона Ресига.

0 голосов
/ 13 июля 2010

Метод JSON.parse самый безопасный. Это определяется, когда вы включаете json2.js из http://www.json.org/js.html и автоматически используется parseJSON / getJSON. Он анализирует вместо выполнения разметки JSON.

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