← 전체 글로 돌아가기

웹 개발

CSP를 한 번에 강제하지 않고 Report-Only로 도입한 순서

콘텐츠 보안 정책으로 화면을 깨뜨리지 않도록 관찰 단계와 강제 단계의 기준을 나눈 노트입니다

보안 헤더를 넣자 화면이 깨질 뻔했다

CSP를 처음 적용하며 script-src self만 넣으면 충분하다고 생각했습니다. 외부 분석 도구와 이미지 호스트가 있는 페이지에서는 콘솔에 위반 보고가 쏟아졌습니다. 바로 강제했다면 클릭 이벤트와 이미지가 사라졌을 상황입니다.

먼저 관찰하기

첫 배포에서는 차단하지 않는 헤더를 사용했습니다.

Content-Security-Policy-Report-Only: default-src 'self'; img-src 'self' https: data:; script-src 'self'; object-src 'none'; base-uri 'self'

blocked-uri와 violated-directive를 묶어 같은 원인을 세고, 필요한 출처인지 화면별로 확인했습니다. 도메인을 전부 허용하지 않고 실제 의존성만 남겼습니다.

nonce가 필요한 경우

인라인 스크립트는 unsafe-inline으로 쉽게 허용하지 않았습니다. 요청마다 nonce를 만들고 헤더와 태그에 같은 값을 넣었습니다. HTML 속성에 섞인 이벤트 핸들러는 nonce 대상이 아니어서 외부 파일이나 React 이벤트로 옮겼습니다.

강제 전환 기준

보고서가 0건이라는 이유만으로 전환하지 않았습니다. 로그인, 이미지 업로드, 결제 전 단계, 관리자 화면을 실제 브라우저에서 확인하고 하루 동안 새 위반이 없는지 봤습니다. 이후 헤더 이름을 강제 모드로 바꾸되 보고는 계속 수집했습니다.

적용 전 점검표

  • 환경별 외부 출처를 확인했는가
  • object-src none과 base-uri self을 포함했는가
  • 인라인 코드를 무조건 허용하지 않았는가
  • 실제 사용자 흐름을 테스트했는가

CSP는 한 줄짜리 만능 설정이 아니라 의존성을 드러내는 관찰 도구였습니다.