[2025-07-11] CSP

🦥 본문

정의

  • 콘텐츠 보안 정책. XSS과 데이터 주입 공격을 탐지하고 완화하는 데 도움이 되는 추가 보안 계층
  • 활성화하기 위해서는 HTTP 헤더를 통해 설정 또는 <meta> 요소를 사용하여 정책 구성

      Content-Security-Policy: default-src 'self' https://example.dreamhack.io
        
      <meta http-equiv="Content-Security-Policy" content="default-src 'self' https://example.dreamhack.io">
    
  • CSP Evalutor : 구글이 CSP가 올바르게 정의하였는 지 검사하는 사이트

Policy Directive

<directive> <value> 형태로 구성. <directive> 는 지시문으로 어떤 리소스에 대한 출처를 제어할 지 결정. <value>는 여러 개의 출처, 공백으로 구분

  • <directive>

    지시어 설명
    default-src 기본 콘텐츠 출처 설정. 다른 모든 리소스가 별도로 지정되지 않으면 이 정책을 따름.
    script-src <script> 로드 가능한 출처 제한. XSS 방지의 핵심.
    style-src <style> 및 CSS 파일의 출처 제한.
    img-src 이미지 파일의 로드 출처.
    font-src 폰트 파일 로드 출처.
    connect-src AJAX, WebSocket, fetch 등의 요청 허용 출처.
    media-src 오디오 및 비디오 리소스 출처.
    object-src <object>, <embed>, <applet> 허용 출처. 보안을 위해 보통 'none'.
    frame-src / child-src iframe의 출처를 지정. child-src는 오래된 버전.
    form-action <form> 제출 대상 제약.
    base-uri <base> 태그의 출처 제한.
    frame-ancestors 현재 페이지를 어떤 사이트가 iframe으로 embed할 수 있는지 제한. X-Frame-Options 대체제.
  • <value>

    | 키워드 | 의미 | | — | — | | 'self' | 현재 페이지의 출처 (same-origin) | | 'none' | 아무 것도 허용하지 않음 | | 'unsafe-inline' | 인라인 <script>, onclick, style 등 허용 (위험) | | 'unsafe-eval' | eval() 같은 문자열 기반 코드 실행 허용 (위험) | | 'strict-dynamic' | 정책에 명시된 스크립트가 로드한 동적 스크립트만 허용, 'self', 'unsafe-inline' 무효화 | | 'nonce-<base64>' | 특정 nonce 값이 있는 <script>만 실행 허용 | | 'sha256-...' | 특정 해시값과 일치하는 인라인 스크립트만 실행 허용 |

    • unsafe-inline과 unsafe-eval은 CSP 무효화에 가까움
    • strict-dynamic은 설정이 까다롭고 호환성 이슈가 있음

기본 정책

  • Inline Code를 유해하다고 간주
    • Inline Code : 태그의 src 속성으로 코드를 로드하지 않고 태그 내에 직접 삽입하는 것. on 이벤트 핸들러 속성, javascript: URL 스킴 등도 인라인으로 간주.

        //inline-code
        <script>alert(1)</script>
        -> <script src="alert.js"></script> 
      
    • CSS 스타일시트 또한 인라인 코드 허용 X

  • 문자열 텍스트를 JS 코드 형태로 변환하는 매커니즘도 유해하다고 간주
    • eval(), new Function(), setTimeout( , …), setInterval( , …)
    • 하지만 위 함수들이 문자열 입력이 아닌 인라인 함수 형태로 파라미터가 전달 될 때에는 차단 X

        setTimeout("alert(1)", ...) ->  차단
        setTimeout(function(){alert(1)}, ...) -> 차단 X 
      

동작 흐름

  1. HTML 수신
  2. CSP 헤더 로딩 : 어떤 리소스를 허용해야 하는 지 저장
  3. HTML 파싱 → 정적 리소스 검사 및 실행 및 정책에 따른 차단 여부 결
  4. 이후에 <sciprt> 태그를 생성할 때마다 해당 <script> 태그 검사

EX)

response.headers['Content-Security-Policy'] = 
	f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'self' 'nonce-{nonce}' 'strict-dynamic'"
  • 기본 콘텐츠 출처는 현재 페이지.
  • 이미지 파일 출처는 dreamhack.io 스타일 출처는 현재 페이지와 인라인 허용
  • script-src는 현재 페이지와 nonce의 출처가 맞는 동적 스크립트만 허용

  • DOM-XSS 문제에서는 HTML 문서 파싱 중에 <script> 태그와 DOM에 새로 생성 되는 <script> 태그는 검사하지만 기존 <script> 태그에 코드가 동적 DOM 삽입은 검사를 안한다.

Categories:

Updated:

Leave a comment