Content Security Policy(CSP)는 무엇이며, 어떻게 활용하나요?

김상욱·2025년 1월 1일
0

Content Security Policy(CSP)는 무엇이며, 어떻게 활용하나요?

Content Security Policy(CSP)는 웹 애플리케이션이 로드할 수 있는 콘텐츠의 출처를 브라우저에게 지시하는 보안 표준. 이를 통해 악성 스크립트나 데이터 주입 공격(예: Cross-Site Scripting, XSS)을 방지할 수 있습니다.
간단히 말해, CSP는 "내 웹사이트는 이 출처에서만 리소스를 로드 할 수 있어"라고 브라우저에 알려주는 규칙 세트입니다.

웹 애플리케이션은 다양한 리소스(스크립트, 스타일시트, 이미지 등)를 외부에서 로드합니다. 하지만 만약 악의적인 사용자가 악성 스크립트를 삽입할 수 있다면, 이는 보안 취약점으로 이어질 수 있습니다. CSP는 다음과 같은 이유로 중요합니다.

  • XSS 공격 방지 : 악성 스크립트가 웹 페이지에 삽입되어 실행되는 것을 방지합니다.
  • 데이터 보호 : 민감한 데이터가 외부로 유출되는 것을 막습니다.
  • 콘텐츠 무결성 유지 : 신뢰할 수 없는 소스의 콘텐츠 로드를 제한하여 웹사이트의 무결성을 유지.

CSP는 다양한 지시자를 통해 어떤 리소스를 허용할지 세부적으로 설정할 수 있습니다.

  • default-src : 기본 리소스 출처를 지정합니다.
  • script-src: 스크립트의 출처를 제한합니다.
  • style-src : 스타일시트의 출처를 제한합니다.
  • img-src : 이미지의 출처를 제한합니다.
  • connect-src: AJAX, WebSocket 등 연결의 출처를 제한합니다.
  • font-src: 폰트의 출처를 제한합니다.
  • object-src : 플러그인 등 객체의 출처를 제한합니다.
  • report-uri : 정책 위반 시 보고할 URI를 지정합니다.
Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com

이 설정은 기본적으로 자신의 도메인('self')에서만 리소스를 로드하고, 스크립트는 자신의 도메인과 http://apis.google.com에서만 로드하도록 허용합니다.

Java/Spring 백엔드에서 CSP 활용

Spring 프레임워크에서는 CSP를 설정하기 위해 Spring Security를 활용할 수 있습니다. Spring Security는 CSP 헤더를 쉽게 추가하고 관리할 수 있는 기능을 제공.

  1. 의존성 추가
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
  1. 보안 설정 클래스 생성
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .headers()
                .contentSecurityPolicy("default-src 'self'; script-src 'self' https://apis.google.com")
                .and()
            .and()
                .authorizeRequests()
                    .anyRequest().authenticated();
    }
}
  1. 테스트 및 검증

고려사항

  • 너무 엄격한 정책은 정상적인 리소스 로드를 방해할 수 있으므로, 필요한 출처만 허용하도록 신중하게 설정해야 합니다.
  • 개발 단계에서는 CSP를 완화한 설정으로 적용하여 기능을 확인한 후, 프로덕션 환경에서는 엄격하게 설정하는 것이 좋습니다.
  • report-uri 지시자를 사용하여 CSP 위반 사항을 모니터링하고, 필요한 경우 정책을 조정할 수 있습니다.

취업 준비 중인 신입 Java 및 Spring 백엔드 개발자라면, Content Security Policy (CSP)를 이해하고 실제로 구현해보는 것이 웹 보안에 대한 이해를 높이고 실무 능력을 키우는 데 큰 도움이 될 것입니다. 다음은 CSP를 실습하기 위한 단계별 가이드와 프로젝트 아이디어를 제안드립니다.


실습 목표

  1. CSP의 기본 개념 이해 및 설정
  2. Spring Security를 사용한 CSP 헤더 설정
  3. CSP 정책의 효과 테스트 및 검증
  4. 실제 웹 애플리케이션에서 CSP 적용 및 문제 해결 경험

1. 개발 환경 준비

필요한 도구 및 기술

  • Java Development Kit (JDK) 11 이상
  • Spring Boot (최신 버전 권장)
  • Maven 또는 Gradle 빌드 도구
  • IDE (IntelliJ IDEA, Eclipse 등)
  • Git 및 GitHub (버전 관리 및 프로젝트 호스팅)
  • 브라우저 (Chrome, Firefox 등) 및 개발자 도구

2. 간단한 Spring Boot 웹 애플리케이션 생성

단계 1: 프로젝트 생성

  1. Spring Initializr를 사용하여 새로운 Spring Boot 프로젝트를 생성합니다.
    • Spring Initializr에 접속합니다.
    • Project: Maven Project
    • Language: Java
    • Spring Boot: 최신 안정 버전 선택
    • Dependencies:
      • Spring Web
      • Spring Security
      • Thymeleaf (또는 다른 템플릿 엔진)
  2. 프로젝트 다운로드 후, IDE에서 엽니다.

단계 2: 기본 페이지 생성

  1. 컨트롤러 생성:

    package com.example.cspdemo.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class HomeController {
    
        @GetMapping("/")
        public String home(Model model) {
            model.addAttribute("message", "안녕하세요! CSP 실습 페이지입니다.");
            return "home";
        }
    }
  2. 템플릿 파일 생성 (src/main/resources/templates/home.html):

    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <title>CSP 실습</title>
        <script src="https://apis.google.com/js/api.js"></script>
        <script>
            // 간단한 스크립트
            console.log("CSP 실습 스크립트 로드 완료.");
        </script>
    </head>
    <body>
        <h1 th:text="${message}"></h1>
        <img src="https://via.placeholder.com/150" alt="샘플 이미지">
    </body>
    </html>

3. Spring Security를 이용한 CSP 설정

단계 1: Spring Security 설정 클래스 생성

src/main/java/com/example/cspdemo/config/SecurityConfig.java 파일을 생성하고 다음과 같이 작성합니다:

package com.example.cspdemo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().permitAll() // 모든 요청을 허용 (단순화)
                .and()
            .headers()
                .contentSecurityPolicy("default-src 'self'; script-src 'self' https://apis.google.com")
                .and()
                .frameOptions().deny(); // Clickjacking 방지
    }
}

설명:

  • default-src 'self': 기본적으로 자신의 도메인에서만 리소스를 로드하도록 설정.
  • script-src 'self' https://apis.google.com: 스크립트는 자신의 도메인과 Google API에서만 로드 허용.
  • frameOptions().deny(): 프레임을 통한 사이트 내재화를 금지하여 Clickjacking 공격 방지.

단계 2: 애플리케이션 실행 및 헤더 확인

  1. 애플리케이션 실행:
    mvn spring-boot:run
  2. 브라우저에서 확인:
    • http://localhost:8080/에 접속합니다.
    • 개발자 도구를 열고, Network 탭에서 응답 헤더를 확인합니다.
    • Content-Security-Policy 헤더가 설정되었는지 확인합니다.

4. CSP 정책 테스트 및 검증

단계 1: CSP 정책 위반 시도

  1. 악의적인 스크립트 삽입:
    • home.html에 다음과 같은 스크립트를 추가해봅니다:
      <script>
          alert("CSP 테스트: 이 스크립트는 차단되어야 합니다.");
      </script>
  2. 페이지 새로고침:
    • 브라우저에서 페이지를 새로고침합니다.
    • 콘솔에 CSP 관련 오류 메시지가 나타나고, alert 창이 실행되지 않는지 확인합니다.

단계 2: 허용된 리소스 테스트

  1. 허용된 스크립트 사용:
    • home.html에 Google API에서 제공하는 스크립트를 추가합니다:
      <script src="https://apis.google.com/js/api.js"></script>
      <script>
          // Google API 스크립트 사용 예제
          gapi.load('client', () => {
              console.log("Google API 로드 완료.");
          });
      </script>
  2. 페이지 새로고침:
    • 스크립트가 정상적으로 로드되고 실행되는지 확인합니다.

단계 3: CSP 위반 보고 설정 (선택 사항)

  1. CSP 보고 URI 추가:

    • SecurityConfig 클래스에서 report-uri 지시자를 추가합니다:
      .contentSecurityPolicy("default-src 'self'; script-src 'self' https://apis.google.com; report-uri /csp-report")
  2. 보고 수신 엔드포인트 생성:

    • CSP 위반 사항을 수신할 컨트롤러를 생성합니다:

      package com.example.cspdemo.controller;
      
      import org.springframework.http.HttpStatus;
      import org.springframework.http.ResponseEntity;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RestController;
      
      @RestController
      public class CSPReportController {
      
          @PostMapping("/csp-report")
          public ResponseEntity<Void> handleCspReport(@RequestBody String report) {
              System.out.println("CSP Report: " + report);
              return new ResponseEntity<>(HttpStatus.NO_CONTENT);
          }
      }
  3. CSP 위반 시도 및 로그 확인:

    • 위반 스크립트를 다시 삽입하고 페이지를 새로고침하면, 서버 로그에 CSP 위반 보고가 출력되는지 확인합니다.

5. 확장된 실습: 실제 웹 애플리케이션에 CSP 적용

프로젝트 아이디어: 간단한 블로그 플랫폼

  1. 기능 구현:

    • 사용자 인증: Spring Security를 사용하여 사용자 로그인 및 인증 기능 구현.
    • 게시글 작성 및 조회: 사용자들이 게시글을 작성하고 조회할 수 있는 기능.
    • 댓글 기능: 게시글에 댓글을 달 수 있는 기능.
  2. CSP 적용:

    • 기본 정책 설정: default-src 'self', 필요한 리소스 출처 추가.
    • 동적 콘텐츠 처리: 사용자 입력을 안전하게 처리하여 XSS 공격 방지.
    • 외부 API 통합: 예를 들어, 외부 이미지 호스팅 서비스 사용 시 img-src 지시자에 추가.
  3. 보안 테스트:

    • XSS 공격 시도: 댓글 입력란에 스크립트를 삽입해보고, CSP가 이를 차단하는지 확인.
    • 리소스 로드 검증: 외부 스크립트나 스타일시트 로드가 필요한 경우 CSP 정책을 적절히 조정.
  4. 보고 기능 활용:

    • CSP 위반 보고: report-uri 또는 report-to 지시자를 설정하고, 위반 사항을 모니터링하여 정책 개선.

실습 단계 요약

  1. 프로젝트 설정 및 기본 기능 구현.
  2. Spring Security를 사용하여 기본 CSP 헤더 설정.
  3. 애플리케이션을 실행하고 CSP 헤더가 올바르게 적용되었는지 확인.
  4. 의도적으로 CSP 위반을 유발하여 보호 기능 검증.
  5. 필요한 리소스 출처를 허용하며 정책을 조정.
  6. CSP 보고 기능을 구현하여 위반 사항을 모니터링.

6. 추가 학습 자료 및 참고 문서


결론

CSP는 웹 애플리케이션 보안의 중요한 요소 중 하나입니다. 신입 개발자로서 CSP를 실습하고 이해하는 것은 실제 프로젝트에서 발생할 수 있는 보안 위협을 예방하는 데 큰 도움이 됩니다. 위의 단계별 가이드를 따라가며 CSP를 직접 구현하고, 다양한 시나리오에서 그 효과를 검증해보세요. 이를 통해 보안에 대한 깊은 이해와 실무 적용 능력을 갖추게 될 것입니다.

궁금한 점이 있거나 추가적인 도움이 필요하면 언제든지 질문해 주세요. 성공적인 취업 준비를 응원합니다!

0개의 댓글