[javascript] JavaScript의 eval ()은 언제 사악하지 않습니까?

스프레드 시트와 같은 기능을 위해 사용자가 입력 한 함수를 구문 분석하기 위해 JavaScript 코드를 작성하고 있습니다. 나는 수식 구문 분석하는 데 수있는 자바 스크립트로 변환하고 실행 eval()결과를 산출하는 데에있다.

그러나, 나는 eval()그것이 악하기 때문에 피할 수 있다면 항상 사용 하지 말았습니다. ).

그렇다면 언제 사용해도 되나요?



답변

귀하의 질문의 전제를 해결하기 위해 잠시 시간을 내고 싶습니다-eval ()은 ” “입니다. 프로그래밍 언어 사용자가 사용하는 ” ” 이라는 단어 는 일반적으로 “위험한”또는보다 정확하게는 “단순한 명령으로 많은 해를 입힐 수 있음”을 의미합니다. 언제 위험한 것을 사용해도 되나요? 위험이 무엇인지, 적절한 예방 조치를 취할 때.

지금까지 eval ()을 사용할 때의 위험을 살펴 보자. 아마도 다른 모든 것과 마찬가지로 작은 숨겨진 위험이 많을 수도 있지만, eval ()이 악하다고 여겨지는 두 가지 큰 위험은 성능과 코드 삽입입니다.

  • 성능-eval ()은 인터프리터 / 컴파일러를 실행합니다. 코드가 컴파일되면 런타임 중에 무거운 컴파일러를 호출해야하기 때문에 큰 타격입니다. 그러나 JavaScript는 여전히 대부분 통역 언어이므로 eval ()을 호출하는 것이 일반적인 경우에 큰 영향을 미치지는 않습니다 (그러나 아래의 특정 설명 참조).
  • 코드 삽입-eval ()은 높은 권한으로 잠재적으로 코드 문자열을 실행합니다. 예를 들어, 관리자 / 루트로 실행중인 프로그램은 입력이 “rm -rf / etc / important-file”이상일 수 있으므로 사용자 입력을 eval ()하기를 원하지 않습니다. 프로그램이 사용자의 계정에서 실행되고 있기 때문에 브라우저의 JavaScript에는 문제가 없습니다. 서버 측 JavaScript에 문제가있을 수 있습니다.

당신의 특정한 경우에. 내가 이해 한 바에 따르면, 문자열을 직접 생성하고 있으므로 “rm -rf something-important”와 같은 문자열이 생성되지 않도록주의를 가정하면 코드 삽입 위험이 없습니다 (그러나 매우 중요합니다. 일반적인 경우에는 이것을 보장하기 어렵다 ). 또한 브라우저에서 실행하는 경우 코드 삽입이 매우 위험합니다.

성능에 관해서는 코딩의 용이성에 대해 가중치를 부여해야합니다. 수식을 구문 분석하는 경우 다른 구문 분석기 (eval () 내부의 구문 분석기)를 실행하지 않고 구문 분석 중에 결과를 계산할 수도 있다고 생각합니다. 그러나 eval ()을 사용하여 코딩하는 것이 더 쉬울 수 있으며 성능 저하는 눈에 띄지 않을 것입니다. 이 경우 eval ()은 시간을 절약 할 수있는 다른 함수보다 더 나쁘지 않습니다.


답변

eval()악하지 않다. 또는 다른 언어에서는 리플렉션, 파일 / 네트워크 I / O, 스레딩 및 IPC가 “악”인 것과 같은 방식으로 악합니다.

, 경우 당신의 목적을 위해 , eval()수동 해석보다 빠르게, 또는 코드가 간단하고, 또는 더 명확하게 … 당신은 그것을 사용해야합니다. 둘 다 아니라면 안됩니다. 그렇게 간단합니다.


답변

출처를 신뢰할 때

JSON의 경우 소스를 제어하는 ​​웹 서버에서 제공되므로 소스를 변경하기가 다소 어렵습니다. JSON 자체에 사용자가 업로드 한 데이터가 없으면 eval을 사용하는 데 큰 결점이 없습니다.

다른 모든 경우에는 eval ()에 공급하기 전에 사용자가 제공 한 데이터가 내 규칙을 준수하는지 확인하기 위해 많은 시간을 할애합니다.


답변

진짜 사람들을 만나자 :

  1. 모든 주요 브라우저에는 이제 해커가 풍부하게 사용할 수있는 콘솔이 내장되어 있습니다. 가능한 경우에도 eval 문을 사용하는 이유가 무엇입니까?

  2. 2000 줄의 JavaScript를 컴파일하는 데 0.2 초가 걸리는 경우 4 줄의 JSON을 평가하면 성능이 어떻게 저하됩니까?

‘eval is evil’에 대한 Crockford의 설명조차 약합니다.

eval은 악, eval 함수는 JavaScript에서 가장 많이 사용되는 기능입니다. 피하세요

Crockford 자신도 “이러한 진술은 비이성적 인 신경증을 유발하는 경향이 있습니다. 그것을 사지 마십시오.”

평가를 이해하고 언제 유용한 지 아는 것이 더 중요합니다. 예를 들어, eval은 소프트웨어에서 생성 된 서버 응답을 평가하는 데 유용한 도구입니다.

BTW : Prototype.js는 eval을 직접 5 번 호출합니다 (evalJSON () 및 evalResponse () 포함). jQuery는 parseJSON에서 (함수 생성자를 통해) 사용합니다.


답변

에 대한 Crockford의 조언 을 따르는 경향이 eval()있습니다. 그것을 요구하는 것처럼 보이는 방법조차도 필요하지 않습니다. 예를 들어, setTimeout()eval 대신 함수를 전달할 수 있습니다.

setTimeout(function() {
  alert('hi');
}, 1000);

그것은 경우에도 신뢰할 수있는 소스 JSON에 의해 반환 된 코드는 기껏 뭔가 남았습니다가, 최악의, 뭔가 나쁜 노출 할 수있는 왜곡 될 수 있기 때문에, 나는 그것을 사용하지 마십시오.


답변

나는 사람들이 있기 때문에, 평가를 사용하지 옹호했다 , 그러나 나는 그들이 평가를 사용하므로 같은 사람이 동적으로 기능과의 setTimeout을 사용했다 후드 아래 : D를

BTW, 샌드 박스가 확실하지 않은 경우 (예 : 코드 삽입을 허용하는 사이트에서 작업중인 경우) eval이 마지막 문제입니다. 보안의 기본 규칙은 모든 입력이 악의적이지만 JavaScript의 경우 JavaScript 자체도 악의적 일 수 있습니다. JavaScript에서는 모든 기능을 덮어 쓸 수 있고 실제 기능을 사용하고 있는지 확신 할 수 없기 때문입니다. 악성 코드가 시작되기 전에 JavaScript 내장 기능을 신뢰할 수 없습니다 : D

이제이 게시물의 서사시는 다음과 같습니다.

당신이 정말로 그것을 필요로하고 (시간의 80 %가 필요 하지 않음 ) 당신이하고있는 일을 확신한다면, eval (또는 더 나은 기능;)을 사용하십시오. 폐쇄와 OOP는 80/90 %의 다른 종류의 논리를 사용하여 eval을 대체 할 수있는 경우 나머지는 동적으로 생성 된 코드 (예 : 인터프리터를 작성하는 경우)이며 이미 JSON을 평가한다고 말했듯이 (여기서는 Crockford 안전 평가를 사용할 수 있습니다.)


답변

Eval은 코드 템플릿에 사용되는 컴파일을 보완합니다. 템플릿을 사용하면 개발 속도를 높이는 유용한 템플릿 코드를 생성하는 단순화 된 템플릿 생성기를 작성합니다.

개발자가 EVAL을 사용하지 않는 프레임 워크를 작성했지만 프레임 워크를 사용하므로 템플릿을 생성하려면 EVAL을 사용해야합니다.

다음 방법을 사용하여 EVAL의 성능을 향상시킬 수 있습니다. 스크립트를 실행하는 대신 함수를 반환해야합니다.

var a = eval("3 + 5");

그것은 다음과 같이 구성되어야합니다

var f = eval("(function(a,b) { return a + b; })");

var a = f(3,5);

캐싱 f는 확실히 속도를 향상시킵니다.

또한 Chrome에서는 이러한 기능을 매우 쉽게 디버깅 할 수 있습니다.

보안과 관련하여 eval 사용 여부는 거의 차이가 없습니다.

  1. 우선, 브라우저는 샌드 박스에서 전체 스크립트를 호출합니다.
  2. EVAL에서 사악한 코드는 브라우저 자체에서 사악합니다. 공격자 또는 누구나 DOM에 스크립트 노드를 쉽게 주입하고 평가할 수 있으면 무엇이든 할 수 있습니다. EVAL을 사용하지 않으면 아무런 차이가 없습니다.
  3. 유해한 서버 측 보안은 대부분 열악합니다. 쿠키 유효성 검사가 불량하거나 서버에서 ACL을 잘못 구현하면 대부분의 공격이 발생합니다.
  4. Java의 네이티브 코드에는 최근 Java 취약점 등이있었습니다. 자바 스크립트는 샌드 박스에서 실행되도록 설계되었으며 애플릿은 인증서 등을 사용하여 샌드 박스 외부에서 실행되도록 설계되어 취약점 및 기타 여러 가지 사항을 초래합니다.
  5. 브라우저를 모방하기위한 코드 작성은 어렵지 않습니다. 즐겨 사용하는 사용자 에이전트 문자열을 사용하여 서버에 HTTP 요청을하면됩니다. 모든 테스트 도구는 브라우저를 조롱합니다. 공격자가 당신에게 피해를 입히고 싶다면 EVAL이 최후의 수단입니다. 서버 측 보안을 처리하는 다른 많은 방법이 있습니다.
  6. 브라우저 DOM은 사용자 이름이 아닌 파일에 액세스 할 수 없습니다. 실제로 eval이 액세스 할 수있는 시스템은 없습니다.

서버 측 보안이 어느 곳에서나 공격 할 수있을 정도로 견고하다면 EVAL에 대해 걱정할 필요가 없습니다. 앞에서 언급했듯이 EVAL이 존재하지 않으면 공격자는 브라우저의 EVAL 기능에 관계없이 서버를 해킹 할 수있는 많은 도구를 가지고 있습니다.

Eval은 미리 사용되지 않은 것을 기반으로 복잡한 문자열 처리를 수행하기 위해 일부 템플릿을 생성하는 데만 적합합니다. 예를 들어 선호합니다

"FirstName + ' ' + LastName"

반대로

"LastName + ' ' + FirstName"

내 표시 이름으로 데이터베이스에서 가져올 수 있고 하드 코딩되지 않았습니다.