flawopen.com/Разбор JSON/JSON.parse() vs eval()
JSON.parse() безопаснее, чем eval()?
Представьте входные данные как записку: JSON.parse() считывает поля структурированной формы, а eval() передает записку интерпретатору как инструкции для выполнения. JSON.parse() следует грамматике JSON и не выполняет JavaScript из текста; полученные значения все равно нужно проверить перед использованием.
// Не интерпретируйте недоверенные данные как исходный код.
const data = eval("(" + untrustedJson + ")");
const data = JSON.parse(untrustedJson);
// Разбор JSON как данных; неверный JSON вызывает SyntaxError.
Почему возникает этот вопрос
До широкого распространения JSON.parse() некоторые старые программы на JavaScript использовали eval() для чтения JSON, поскольку текст JSON пересекается с синтаксисом выражений JavaScript. Такой подход выполняет программу JavaScript: данные под контролем атакующего могут стать кодом, а не ограниченным набором значений JSON. Для JSON используйте JSON-парсер.
От чего JSON.parse() не защищает
JSON.parse() не проверяет бизнес-правила, не авторизует действия и не делает разобранные значения безопасными для HTML, SQL, команд оболочки или URL. Проверяйте ожидаемую структуру данных и применяйте контекстное кодирование вывода или параметризованные API. Если передан reviver, предоставленный приложением callback выполняется во время разбора; он должен быть доверенным, простым и не создавать побочных эффектов на основе значений под контролем атакующего.
Вопросы и ответы
Сам текст JSON разбирается как данные, а не выполняется как JavaScript. Но если приложение передает reviver, этот доверенный callback вызывается для разобранных значений и может выполнять код. Не позволяйте данным под контролем атакующего выбирать или создавать исполняемую логику callback.
Нет. Сверяйте разобранное значение с ожидаемой схемой приложения и правилами авторизации. Для HTML используйте кодирование вывода, для SQL — параметризованные запросы; разбор не очищает данные для этих контекстов.