웹사이트를 운영하거나 웹 서비스를 이용하는 분이라면 ‘보안’이라는 단어가 낯설지 않으실 겁니다. 특히 ‘XSS(Cross-Site Scripting)’ 공격은 웹에서 가장 흔하게 발생하는 취약점 중 하나로, 사용자에게 심각한 피해를 줄 수 있습니다. 하지만 걱정하지 마세요. Content Security Policy, 즉 CSP라는 강력한 방어막으로 XSS 공격을 효과적으로 막아낼 수 있습니다. 이 가이드에서는 CSP가 무엇인지, 왜 중요한지, 그리고 어떻게 설정하여 여러분의 웹사이트를 안전하게 보호할 수 있는지 쉽고 실용적인 방법으로 알려드립니다.
웹 보안의 골칫거리 XSS 공격이란 무엇인가요
XSS 공격은 공격자가 악성 스크립트를 웹사이트에 주입하여, 해당 웹사이트를 방문하는 다른 사용자들의 웹 브라우저에서 실행되도록 하는 기법입니다. 쉽게 말해, 웹사이트가 사용자에게 보여주는 내용에 공격자가 몰래 악성 코드를 심어 넣는 것이죠. 이 악성 코드는 사용자 세션 하이재킹, 민감 정보 탈취, 악성 콘텐츠 유포 등 상상 이상의 피해를 일으킬 수 있습니다.
예를 들어, 게시판에 글을 남기는 기능이나 검색창에 특정 문구를 입력하는 기능 등 사용자의 입력을 받는 모든 곳에서 XSS 공격이 발생할 수 있습니다. 웹사이트 관리자가 사용자 입력을 제대로 검증하거나 필터링하지 않으면, 공격자는 입력란에 자바스크립트 코드를 넣어 웹사이트에 반영되게 할 수 있습니다. 그리고 다른 사용자가 이 게시물을 보거나 검색 결과를 클릭하면, 그 사용자의 브라우저에서 공격자의 스크립트가 실행되는 것입니다.
이러한 XSS 공격은 웹사이트의 신뢰도를 떨어뜨리고, 사용자들에게 직접적인 금전적, 개인 정보 피해를 입힐 수 있기 때문에 반드시 막아야 합니다.
Content Security Policy CSP는 왜 중요하고 어떻게 작동하나요
CSP는 웹사이트가 로드할 수 있는 리소스(스크립트, 스타일시트, 이미지 등)의 출처를 명시적으로 지정하여, 신뢰할 수 없는 출처의 리소스가 실행되는 것을 차단하는 보안 메커니즘입니다. 마치 ‘이 웹사이트는 오직 이 주소에서 온 스크립트만 허용합니다’라고 선언하는 것과 같습니다. 이는 XSS 공격 방어에 매우 효과적인 방법입니다.
CSP는 웹 서버가 HTTP 응답 헤더에 `Content-Security-Policy`라는 이름으로 정책을 전송하거나, HTML 문서 내 `` 태그를 통해 정책을 선언함으로써 작동합니다. 브라우저는 이 정책을 읽고, 페이지에 포함된 모든 리소스가 정책에 명시된 출처에서 왔는지 확인합니다. 만약 정책에 허용되지 않은 출처의 리소스가 발견되면, 브라우저는 해당 리소스의 로드를 차단하고, 필요하다면 웹사이트 관리자에게 위반 사실을 보고합니다.
이러한 CSP의 작동 방식은 기존의 XSS 방어 기법들이 주로 ‘블랙리스트’ 방식(나쁜 것을 걸러내는 방식)이었다면, CSP는 ‘화이트리스트’ 방식(좋은 것만 허용하는 방식)을 채택하여 더욱 강력한 보안을 제공합니다.
CSP 설정 어떻게 시작하나요
CSP를 설정하는 것은 생각보다 복잡하지 않습니다. 단계적으로 접근하면 쉽게 적용할 수 있습니다. 가장 기본적인 단계는 `Content-Security-Policy` HTTP 헤더를 웹 서버 응답에 추가하는 것입니다.
가장 기본적인 CSP 정책 만들기
CSP 정책은 여러 지시어(Directive)와 해당 지시어에 대한 허용 출처 목록으로 구성됩니다. 가장 기본적인 정책은 `default-src` 지시어를 사용하여 모든 종류의 리소스에 대한 기본 출처를 정의하는 것입니다.
default-src 'self': 모든 리소스(스크립트, 스타일, 이미지 등)의 출처를 현재 웹사이트의 도메인으로 제한합니다. 즉, 외부에서 가져오는 리소스는 허용하지 않습니다.
이 정책을 HTTP 응답 헤더에 추가하면 됩니다. 예를 들어, Nginx 웹 서버에서는 다음과 같이 설정할 수 있습니다.
add_header Content-Security-Policy "default-src 'self';";
Apache 웹 서버에서는 `.htaccess` 파일이나 가상 호스트 설정에 다음과 같이 추가할 수 있습니다.
Header set Content-Security-Policy "default-src 'self';"
이렇게 설정하면, 현재 웹사이트 도메인 외의 다른 곳에서 로드하려는 모든 스크립트나 이미지는 브라우저에 의해 차단됩니다.
보고서 전용 모드 Report-Only로 안전하게 시작하기
CSP를 처음 적용할 때는 `Content-Security-Policy-Report-Only` 헤더를 사용하는 것이 좋습니다. 이 헤더는 정책을 위반하는 리소스가 있더라도 실제로 차단하지 않고, 단지 위반 사실만 보고하도록 합니다.
Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report-endpoint;"
이 모드를 사용하면 웹사이트의 기능에 영향을 주지 않으면서, 어떤 리소스들이 정책을 위반하는지 파악하고 정책을 완벽하게 조정할 수 있습니다. `report-uri` 지시어는 위반 보고서를 받을 URL을 지정합니다. 이 URL은 서버 측에서 위반 보고서를 수집하고 분석하는 엔드포인트가 되어야 합니다.
주요 CSP 지시어 자세히 살펴보기
CSP는 다양한 종류의 리소스에 대해 세부적인 제어를 가능하게 하는 여러 지시어를 제공합니다. 몇 가지 핵심 지시어를 살펴보겠습니다.
default-src
모든 종류의 리소스에 대한 기본 출처를 정의합니다. 특정 리소스 타입(예: 스크립트, 스타일)에 대한 지시어가 명시되지 않은 경우, `default-src`의 정책을 따릅니다. 따라서 항상 `default-src`를 먼저 정의하고, 필요한 경우 다른 지시어로 세부적인 예외를 설정하는 것이 좋습니다.
- 예시:
default-src 'self' cdn.example.com;(현재 도메인과 cdn.example.com만 허용)
script-src
자바스크립트 파일의 로드 출처를 정의합니다. XSS 공격을 방어하는 데 가장 중요한 지시어 중 하나입니다. 인라인 스크립트나 `eval()`과 같은 함수 사용을 제한할 수 있습니다.
- 예시:
script-src 'self' https://ajax.googleapis.com;(현재 도메인과 Google CDN에서만 스크립트 로드 허용)
style-src
CSS 스타일시트의 로드 출처를 정의합니다. 인라인 스타일이나 `