본문 바로가기
Front-end/Javascript

eval()과 CSP

by softserve 2024. 9. 10.
반응형
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script

는 브라우저의 Content Security Policy (CSP) 설정으로 인해 발생하는 문제입니다. CSP는 웹 페이지의 스크립트 실행을 제한하여 보안을 강화합니다. eval()과 같은 위험한 방식이 사용되지 않도록 차단하는 역할을 하죠.

 

1. eval()은 왜 위험하다는 걸까?

 

eval()은 문자열을 Javascript 코드로 해석해 실행합니다.

eval("alert('hello')");

 

new Function()은 동적으로 함수를 생성하는 방법입니다. 

let func = new Function('arg1', 'arg2', 'return arg1 + arg2;')

eval이나 new Function에 사용자가 입력한 문자열을 그대로 전달하게 되면 권한없는 사용자가 코드 인젝션을 통해 시스템에 접근하거나 데이터를 변조할 수 있어 보안상 문제가 됩니다. 따라서 CSP 정책을 수정하는 것보다는 eval()을 제거하여 소스 코드를 보다 안전하게 수정하는 것이 바람직합니다. 불가피하게 써야할 경우 인수를 철저히 검증할 필요가 있습니다.

사용 중인 라이브러리가 오래된 버전이라면, 최신 버전으로 업데이트하는 것도 하나의 방법입니다. 최신 버전에서는 eval() 사용이 최소화되었을 가능성이 있습니다.

 

2. CSP 설정을 확인하고 변경하는 방법

 

만약 보안보다 기능이 더 중요한 경우라면 다음과 같이 메타 태그를 이용해 CSP에 unsafe-eval을 추가해줄 수 있습니다. 

<meta http-equiv="Content-Security-Policy" content="script-src 'self' unsafe-eval;">

이렇게 CSP를 수정하면 eval() 함수 사용으로 인해 스크립트 오류가 발생하는 것을 막을 수 있습니다. 물론 권장하지는 않습니다.

특정 사이트의 CSP 정책을 확인하는 방법은 다음과 같습니다.

 

1) 개발자 도구

개발자 도구(F12)의 Network 탭을 연다음, 새로고침을 해보면 현재 접속한 페이지에서 불러오고 있는 모든 파일의 목록이 나타납니다.

그 중 html 파일을 클릭해보면 우측에 상세 정보가 나타나고, 아래 사진과 같이 Headers에 Content-Security-Policy 항목이 들어있는 것을 확인할 수 있습니다.

네이버 로그인 페이지의 CSP 설정

CSP 설정 중 script-src는 스크립트 소스의 출처를 제어하는 데 사용되는 지시어입니다. 

네이버 로그인 페이지는 아래와 같은 script-src 정책을 가지고 있습니다.

script-src 'nonce-eeCAylgxZSPkHgxVvLY3eAZ5' *.nid.naver.com ssl.pstatic.net wtm.pstatic.net ncpt.naver.com 'wasm-unsafe-eval' 'unsafe-inline' 'self';

 

  • 'nonce-eeCAylgxZSPkHgxVvLY3eAZ5': 이 nonce 값이 포함된 인라인 스크립트만 허용합니다.
  • *.nid.naver.com, ssl.pstatic.net, wtm.pstatic.net, ncpt.naver.com: 특정한 도메인에서 제공하는 스크립트를 허용합니다. naver.com의 하위 도메인과 CDN 도메인을 지정해주고 있네요.
  • 'wasm-unsafe-eval': WebAssembly 모듈의 eval()을 허용합니다
  • 'unsafe-inline': 인라인 스크립트 실행을 허용합니다.
  • 'self': 현재 도메인에서 로드된 스크립트를 허용합니다.

 

2) cURL

서버에 직접 접근하지 않고도 curl 명령어를 사용해 HTTP 응답 헤더를 확인할 수 있습니다.

curl -I <https://your-website-url.com>

 

3) 서버 설정 파일에서 확인 및 수정하기

 

Apache - httpd.conf

# Apache 설정 파일에서 추가할 수 있는 예시
<IfModule mod_headers.c>
    Header set Content-Security-Policy "script-src 'self'; object-src 'none';"
</IfModule>

 

Nginx - nginx.conf

# Nginx 설정 파일에서 추가할 수 있는 예시
server {
    listen 80;
    server_name example.com;

    location / {
        add_header Content-Security-Policy "script-src 'self'; object-src 'none';";
        # 추가 설정...
    }
}

 

Express (Node.js) 서버에서 CSP 설정하기

Node.js 기반의 Express 서버에서는 애플리케이션 코드에서 CSP 헤더를 직접 설정할 수 있습니다.

// Express에서 CSP 설정하기
const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.setHeader("Content-Security-Policy", "script-src 'self'; object-src 'none';");
  next();
});

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

 

반응형

댓글