반응형
콘텐츠 보안 정책 (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>
참고 자료
반응형