Web,Mobile/Tech

eval()과 Function 생성자의 Scope

LimeLee 2024. 1. 12. 19:26

 

eval을 절대 사용하지 말 것!

eval() - JavaScript | MDN

**eval()**은 문자로 표현된 JavaScript 코드를 실행하는 함수입니다.

developer.mozilla.org

 
eval()은 인자로 받은 코드를 caller의 권한으로 수행하는 위험한 함수입니다. Function으로는 실현할 수 없는 공격이 가능합니다.
라고 작성되어있는데 정확히 이게 무슨 소린가 싶다. 그래서 좀 찾아봤다.


 
자바스크립트에는 스코프(Scope)라는게 있는데 전역 스코프, 블록 스코프, 함수 스코프가 존재한다. 

JavaScript Scope

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 letconstvar
유효범위Block ScopeBlock ScopeFunction Scope
값 재정의OXO
재선언XXO

 
출처: https://joooing.tistory.com/entry/Scope

function func() {
    var a = 1;
}

console.log(a);

예로 들면 var a는 func의 함수 스코프에서 유효하므로 func 함수 밖에서 a 변수에 접근할 수 없다.
 
Function 생성자나 eval 함수를 통해 생성된 함수에도 이런 스코프가 존재한다.
Function 생성자는 전역 스코프에서만 실행되는 함수를 만들게 된다.

 
반면 eval()는 caller 권한 즉, 함수 자신을 호출한 함수에 따라 전역 함수가 될 지 내부 함수가 될지 달라진다.
 
 
예시로 사용자의 입력 값이 func()이라는 함수 내 반영되고 eval 또는 Function 생성자를 통해 스크립트를 실행한다면 이런 차이가 발생하게 된다.

eval은 func의 a변수에 접근할 수 있지만 Function은 a변수에 접근할 수 없다.

 

eval("console.log(a)")의 Scope

 

Function("console.log(a)")()의 Scope

 
 


Function 생성자로 실현할 수 없는 특수한 상황이 뭔지는 알겠는데 
 
사용자의 입력 값이

  • 함수 내에 반영되고
  • 스크립트를 임의 실행이 가능하고
  • 함수 내 공격자 관점에서 유의미하게 활용할 수 있는 데이터가 존재하는 경우

같은 제한적인 상황이라서 Function 생성자에 비해 엄청나게 위험한 것 처럼 작성된 이유도 모르겠고 (eval을 절대 사용하지 않아야한다기보다 사용자 입력 값이 스크립트로 해석되지 않는 게 중요한게 아닌지) 자주 써먹을 수 있을지도 잘 모르겠다.