JSON.parse 대 eval ()


94

내 Spider Sense는 eval()들어오는 JSON을 구문 분석 하는 데 사용 하는 것은 나쁜 생각 이라고 경고합니다 . 나는 JSON.parse()브라우저 특정 기능이 아닌 JavaScript의 일부라고 가정하는 것이 더 안전 한지 궁금합니다 .


성능면 에서 적어도 V8 (Chromium의 JS 엔진)에서 JSON.parse보다 빠릅니다 eval. 소스 .
Paul

답변:


110

다음을 사용하는 경우 공격에 더 취약합니다eval . JSON은 Javascript의 하위 집합이고 json.parse는 JSON을 구문 분석하는 반면 eval모든 JS 표현식에 대한 문을 열어 둡니다.


"당신은 공격에 더 취약합니다" , 나는 완전히 동의하지 않습니다!
Hydroper

4
미안 해요, 마테우스, 동의해야합니다. 문제는 eval ()을 사용하여 "사용자 입력"을 해석 할 때입니다. 이는 JavaScript의 외부 소스입니다 (호출 한 서블릿 또는 기타 웹 서비스에서 반환 된 값 포함). 사용자가 클라이언트 앱에 직접 또는 서버의 데이터베이스에 저장된 확인되지 않은 데이터로 인해 간접적으로 악성 JavaScript를 입력하지 않은 다음 AJAX 스타일 호출을 통해 프로그램에 전달되지 않았 음을 보장 할 수 없습니다. "대리인 혼동"공격을 피하기 위해 개별 필드의 유효성을 검사해야 할 수도 있지만 JSON.parse를 사용하는 것이 좋은 첫 번째 단계입니다.
JackLThornton

1
@Hydro 짧은 개념 증명 : 시도해보십시오 eval('alert(1)');.
Valerio Bozz

37

JSON.parse사용 가능성이 가장 높은 모든 구현eval()

JSON.parseDouglas Crockford의 솔루션을 기반으로 합니다. 497 번 라인에서eval() 바로 사용합니다 .

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

j = eval('(' + text + ')');

의 장점은 JSON.parse인수가 올바른 JSON 구문인지 확인한다는 것입니다.


56
예, 그 바로 앞의 줄이 안전하고 유효한 문자열인지 확인하는 것을 제외하고는.
nickf

6
JSON.parse()Linux Mint 시스템에서 Firefox 28 및 Chromium 33에서 테스트 했습니다. eval()Firefox 보다 2 배 빠르며 Chromium에서 4 배 빠릅니다. 어떤 소스 코드를 게시하고 있는지 잘 모르겠지만 내 브라우저에서는 동일하지 않습니다.
jbo5112 2014

@plodder "advantage"는 아마도 그 검증을하기에 저렴하지 않을 것입니다.
mmm

2
최신 브라우저 는 기반 파서 JSON.parse()보다 더 안전하고 빠른 기본 구현을 제공합니다 eval().
Mohammad Alhashash 2016-06-13

15

모든 브라우저가 기본 JSON을 지원하는 것은 아니므로 eval() JSON 문자열 을 사용해야 하는 경우 가 있습니다 . http://json.org의 JSON 파서를 사용하면 모든 것을 훨씬 쉽게 처리 할 수 ​​있습니다.

Eval() 악하지만 일부 브라우저에 대해서는 필요한 악이지만 피할 수있는 곳에서는 그렇게 !!!!!


12

JSON.parse ()와 eval ()이 받아들이는 것에는 차이가 있습니다. 이것에 대해 평가 해보십시오.

var x = "{\"shoppingCartName \ ": \"shopping_cart : 2000 \ "}"

eval(x)         //won't work
JSON.parse(x)   //does work

예를 참조하십시오 .


1
eval은 문자열을 코드 문으로 구문 분석하므로 "{...}"를 값 선언 식 대신 코드 식으로 간주하므로 작동하지 않습니다. 당신이 모호성을 제거하는 경우 ( "[{....}]"예를 들어), 구문 분석 된 오브제 포함하고있는 배열을 생성 할 표현과 평가의 성격에 의심의 여지가
찰스 HETIER

1
예. 전통적으로 x는 eval ( "("+ x + ")")와 같이 괄호로 둘러싸여 있습니다. 내가 말한 내용은 여전히 ​​유효합니다. JSON.parse ()를 사용할 때 모호성이 없습니다.
Jeff Lowery 2014

9

를 사용하여 JSON을 구문 분석하면 구문 분석되는 eval문자열에 모든 것이 포함되도록 허용하므로 데이터 집합이되는 대신 함수 호출 등을 실행하는 자신을 찾을 수 있습니다.

또한 JSON parse은 datetimes와 같은 특정 값을 처리하는 방법을 지정할 수있는 추가 매개 변수 인 reviver를 허용합니다 ( 여기 인라인 문서에서 자세한 정보 및 예제 참조 ).


4

JSON은 JavaScript의 일부일뿐입니다. 그러나 evalJSON 인 부분 집합 만이 아니라 전체 JavaScript 언어를 평가합니다.


맞아, 알아. JSON.parse ()가 JSON 만 평가하고 다른 모든 수신 데이터에서 실패한다는 것을 의미합니까? 아니면 단순히 래퍼일까요 : var myObject = eval ( '('+ responseText + ')'); ??
케빈 주요

6
@Kevin Major : 예, 기본적으로 구현 된 JSON.parse(JavaScript 엔진에 직접 구현 된) JSON 만 구문 분석합니다. 그러나 기본이 아닌 다른 구현에서는 온 전성 검사를 수행 한 다음 eval성능상의 이유로 사용 합니다.
Gumbo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.