본문 바로가기
웹 개발

CSP 보안설정

by Jaejin Sim 2018. 4. 18.
반응형

콘텐츠 보안 정책 (CSP) 가이드

CSP란?

**CSP (Content-Security-Policy)**는 Mozilla가 개발한 표준으로, 브라우저에서 XSS (Cross Site Scripting) 공격을 막는 것을 목표로 합니다.

주요 특징

  • 인라인 스크립트를 기본적으로 금지
  • 필요시 nonce를 사용하여 특정 스크립트만 허용 가능
  • FACEBOOK, 트위터, 깃허브, 인스타그램 등 다양한 서비스에서 사용 중

브라우저 호환성

  • IE: 엣지부터 지원
  • 모바일 브라우저: 거의 모든 브라우저에서 지원
  • 상세 호환성은 Can I use CSP 참고

CSP 지시문 및 옵션

지시문 설명

default-src 디폴트 설정
connect-src 연결할 수 있는 URL을 제한 (ajax, websockets 등)
script-src 스크립트 관련 권한 집합을 제어
child-src iframe 태그에서 사용
style-src 스타일시트 관련 권한 집합을 제어
font-src 웹 글꼴을 제공할 수 있는 출처를 지정
img-src 이미지 관련 권한 집합을 제어
report-uri CSP 위반 시 브라우저가 보고서를 보낼 URL 지정 (meta 태그에서는 사용 불가)

src 옵션 설정

  • 도메인 지정: http://www.test.com, example.com, example.com:443 등 접근 허용 도메인
  • 'none': 모든 것을 차단(잠금)
  • 'self': 현재 도메인만 허용
  • 'unsafe-inline': 소스코드 내 인라인 자바스크립트 및 CSS를 허용
  • 'nonce-암호화된문자': 특정 인라인 자바스크립트 및 CSS를 허용

CSP 설정 방법

1. Meta 태그 설정

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'; style-src 'self';">

2. PHP Header 설정

<?php
$headerCSP = "Content-Security-Policy:".
    "default-src 'self';".  // 기본은 자기 도메인만 허용
    "connect-src 'self';".  // ajax url은 자기 도메인만 허용    
    "script-src 'self' example.com code.jquery.com https://ssl.google-analytics.com;".
    "style-src 'self' 'unsafe-inline';".
    "report-uri https://example.com/csp_report.php;";  // 보안 정책 오류 레포트 URL 지정
header($headerCSP);
?>

3. CSP 적용 예시

위의 PHP header 정책을 바탕으로 한 사용 가능/불가능 예시:

<!-- ✅ 사용가능 (접근허용도메인) -->
<script src='www.example.com/js/script.js'></script>

<!-- ✅ 사용가능 (접근허용도메인) -->
<script src='https://ssl.google-analytics.com/js/script.js'></script>

<!-- ✅ 사용가능 (self) -->
<script src='/js/script.js'></script>

<!-- ❌ 사용 불가능 (허용되지 않은 도메인) -->
<script src='www.test.com/js/script.js'></script>

<!-- ❌ 사용 불가능 (인라인 스크립트) -->
<script>alert('인라인스크립트 허용안함');</script>

<!-- ✅ 사용가능 (self) -->
<link rel="stylesheet" href="/css/common.css">

<!-- ✅ 사용가능 (unsafe-inline) -->
<span style='color:green;'>인라인스타일 허용</span>

<!-- ❌ 사용 불가능 (허용되지 않은 도메인) -->
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">

CSP 보안위반 REPORT 설정

위반 시 동작

보안 정책 위반 시 브라우저 콘솔에 오류 정보가 노출되며, report-uri 설정을 통해 서버로 리포트를 받을 수 있습니다.

리포트 처리 예시 (PHP)

csp_report.php 파일:

<?php
$postdata = file_get_contents("php://input");
$data = json_decode(trim($postdata), true);

$log = "================ CSP REPORT 로그 파일 (".date('Y-m-d H:i:s').") =============\n";
$fp = fopen('/var/www/html/sim/log/csp_log.txt', 'a');
fwrite($fp, $log);
fwrite($fp, var_export($data, true)."\n");
fclose($fp);
?>

리포트 데이터 구조

필드 설명

document-uri 위반이 발생한 페이지
original-policy CSP 전체 정책
violated-directive 위반한 특정 지시문
blocked-uri 정책을 위반한 리소스

CSP NONCE 설정

unsafe-inline 옵션보다 더 보안이 강화된 방법으로, 특정 인라인 스크립트만 허용할 수 있습니다.

Nonce 생성 및 사용

// PHP에서 nonce 생성
$nonce_key = hash('sha256', microtime());

CSP 헤더 설정

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

HTML에서 사용

<!-- ✅ 사용가능 (nonce 일치) -->
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
    alert('해당 스크립트는 사용가능한 인라인 스크립트입니다.');
</script>

<!-- ❌ 사용 불가능 (nonce 없음) -->
<script>
    alert('해당 스크립트는 사용 불가능한 인라인 스크립트입니다.');
</script>

참고 자료

반응형