[Effective JavaScript] eval을 이용해 지역 변수를 생성하지 말자

김범식·2023년 6월 26일
0

Effective JavaScript

목록 보기
10/33
post-thumbnail

eval() 이란?

eval() 함수는 전달된 문자열을 JavaScript 코드로 해석하고 실행한다.

eval(code)



사용예시

var x = 5;
var code = "console.log(x + 10);"; // 실행할 코드를 문자열로 정의

eval(code); // 결과: 15



사용시 주의해야 할 점

  • 보안상의 이슈를 일으킬 수 있다. (인젝션 이슈)
  • 코드의 가독성과 유지보수성을 저하시킬 수 있다.



이처럼 eval 함수는 유연하고 강력한 도구다. 때문에 제대로 이해해 두는 것이 좋다.

eval의 이상한 동작을 확인하기 위한 가장 쉬운 방법은 스코프를 침범하게 만드는 것이다.

eval 은 자신의 인자를 자바스크립트 프로그램처럼 해석하지만, 이 프로그램은 호출자의 지역 스코프 안에서 실행된다. 임베디드된 프로그램의 전역변수는 호출한 프로그램의 지역변수로 생성된다.

function test(x){
	eval("var y = x;");
	return y;
}
test("hello").  //hello



여기서 var 선언문은 오직 eval 함수가 호출될 때에만 실행된다. eval을 조건적인 문맥에 위치시키면 해당 조건문이 실행될 때에만 그 변수를 스코프 내로 가져오게 된다.

var y = "global"
function test(x){
	if(x){
		eval("var y = 'loacl';");    //동적 바인딩
	}
	return y;
}

test(true); // "local"
test(false); // "global"

스코프를 프로그램의 동적인 동작에 의해 결정하는 방법은 대부분의 경우 좋지 않다.



소스코드를 지역적으로 선언하지 않고 다음과 같이 eval에 전달하면 특히 더 교묘해진다.

var y = "global"
function test(src){
		eval(src)
		return y;
}

test("var y = 'local';"); //local
test("var z = 'local';"); //global

이 코드는 불안정하고 안전하지 않다. 외부의 호출자가 test 함수 내부의 스코프를 변경할 수 있기 때문이다. 또한 ES5 스트릭트 모드의 호환성에 적합하지 않다.



eval이 외부 스코프에 영향일 주지 않도록 하는 방법은 감싸진 스코프 안에서 실행되도록 하는것이다.

var y = "global"
function test(src){
		(function(){eval(src)})();
		return y;
}

test("var y = 'local';"); //global
test("var z = 'local';"); //global



기억할 점

  • 호출자의 스코프를 어지럽힐 수 있으므로 eval을 통한 변수 생성을 자제하라
  • eval 코드가 전역 변수르 ㄹ생성할 가능성이 있다면, 스코프 오염을 막기 위해 감싸진 함수 안에서 호출하라
profile
frontend developer

0개의 댓글