Article

JavaScript eval() 사용 금지 및 안전한 대체 방법

개요

JavaScript의 eval() 함수는 문자열을 JavaScript 코드로 실행하는 강력한 기능이지만, 보안 위험, 성능 저하, 코드 복잡성 증가로 인해 사용을 권장하지 않습니다. 이 문서에서는 eval() 없이 동일한 목표를 달성하는 안전한 대체 방법들을 소개합니다.

eval() 사용이 위험한 이유

  1. 보안 취약점: 신뢰할 수 없는 입력을 실행하면 악의적인 코드가 실행될 수 있습니다.
  2. 성능 저하: eval()은 런타임에 코드를 파싱하고 컴파일해야 하므로 느립니다.
  3. 스코프 오염: eval()은 로컬 스코프에 접근할 수 있어 예기치 않은 변수 수정이 가능합니다.
  4. 디버깅 어려움: eval()로 생성된 코드는 스택 추적에서 추적하기 어렵습니다.

대체 방법 1: Function 생성자

문제 상황:

function say() {
    alert('say yo ~');
}

eval('say()');  // 위험

안전한 대체:

function say() {
    alert('say you ~');
}

new Function('return say()')();  // eval보다 안전

Function 생성자는 eval()보다 제한적이어서 더 안전합니다. 단, 여전히 조심해서 사용해야 합니다.

대체 방법 2: 객체 접근 (권장)

문제 상황:

var jsonObj = { lang: 'javascript' };
var objName = 'lang';
console.log(eval("jsonObj." + objName));  // eval 사용

권장 방법:

var jsonObj = { lang: 'javascript' };
var objName = 'lang';
console.log(jsonObj[objName]);  // 객체 접근

이 방법이 가장 간단하고 안전합니다. 동적 객체 접근이 필요하면 괄호 표기법을 사용하세요.

대체 방법 3: 맵/딕셔너리 패턴

동작 선택이 필요한 경우:

// 문제 코드
var action = 'save';
eval(action + '()');  // 위험

// 대체 코드
var actions = {
    save: function() { /* ... */ },
    delete: function() { /* ... */ },
    update: function() { /* ... */ }
};

actions[action]();  // 안전

대체 방법 4: JSON 파싱

JSON 문자열 파싱:

// 문제 코드
var jsonStr = '{"name": "John", "age": 30}';
var obj = eval('(' + jsonStr + ')');  // 위험

// 안전한 대체
var obj = JSON.parse(jsonStr);  // 현대적이고 안전

JSON.parse()는 JSON 형식만 파싱하므로 코드 실행이 불가능하여 매우 안전합니다.

대체 방법 5: 콜백 함수

함수 동작이 필요한 경우:

// 문제 코드
var operation = 'multiply';
var result = eval(operation + '(5, 3)');

// 대체 코드
var operations = {
    add: (a, b) => a + b,
    multiply: (a, b) => a * b,
    divide: (a, b) => a / b
};

var result = operations[operation](5, 3);

상황별 eval() 대체 방법 비교

상황eval()대체 방법장점
객체 속성 접근eval("obj." + key)obj[key]가장 간단하고 안전
함수 호출eval(funcName + '()')functions[funcName]()명확한 의도 표현
JSON 파싱eval('(' + jsonStr + ')')JSON.parse(jsonStr)표준 API, 타입 안전
동적 코드 실행eval(code)new Function(code)()스코프 격리

마치며

JavaScript에서 eval() 사용은 편리할 수 있지만, 보안과 성능 측면에서 심각한 문제를 야기합니다. 다행히 대부분의 eval() 사용 사례에는 더 안전하고 명확한 대체 방법이 존재합니다.

핵심 원칙: eval()이 필요하다고 생각되면, 다시 한 번 생각해보세요. 대부분의 경우 더 안전하고 빠른 대체 방법이 존재합니다.

개발할 때마다 이 원칙을 기억한다면, 더 안전하고 유지보수하기 쉬운 JavaScript 코드를 작성할 수 있을 것입니다.

댓글