한양과학기술고등학교

에듀테크 프로젝트 대시보드

CSP (Content-Security-Policy)

🛡️ CSP (Content-Security-Policy)

브라우저에게 "이 페이지에서는 이 출처의 스크립트·스타일·이미지만 실행/로드해도 돼"라고 알려주는 HTTP 응답 헤더. 서버 코드에 실수로 XSS 취약점이 남아 있어도, CSP가 "마지막 방어선"으로 악성 스크립트 실행을 막아줄 수 있습니다. 아래에서 정책을 직접 조립하고, 공격 시나리오가 통과되는지 막히는지 확인해 보세요.

🧩 정책 빌더 실시간 조립
🖥️ 페이지 미리보기 공격 시나리오
여기에 스크립트/스타일 실행 결과가 표시됩니다.
0
차단됨
0
허용됨
📋 브라우저 콘솔 실시간
// 위 버튼을 눌러 정책을 시험해 보세요...
⚡ CSP 검사 흐름
① 서버 응답 헤더 전송
→
② 브라우저 정책 파싱·저장
↓
③ 리소스 요청마다 출처 검사
→
④ 허용 목록 안 → 실행
↓
⑤ 목록 밖 → 차단 + 콘솔 에러
→
⑥ report-uri로 위반 보고(선택)
CSP는 서버가 아니라 브라우저가 강제합니다. 즉 이미 응답으로 전달된 HTML/스크립트라도, 정책에 어긋나면 브라우저가 실행 직전에 막습니다 — HTML 이스케이프와는 별개의 방어층입니다.
📖 주요 지시어(directive)
지시어의미
default-src나머지 지시어 미지정 시 기본값
script-srcJS 실행 허용 출처
style-srcCSS 적용 허용 출처
img-src이미지 로드 허용 출처
frame-ancestors나를 iframe에 넣을 수 있는 출처 (클릭재킹 방어)
connect-srcfetch/XHR/WebSocket 허용 출처
report-uri위반 발생 시 보고서를 보낼 주소
'unsafe-inline'은 이름 그대로 위험합니다. 인라인 스크립트를 열어주는 순간, CSP가 막으려던 XSS 실행 경로가 그대로 살아납니다. 대신 nonce-랜덤값이나 sha256-해시로 "이 스크립트 블록만" 예외 허용하는 방식을 씁니다.
🐍 FastAPI 미들웨어 적용
@app.middleware("http") async def add_csp(request, call_next): resp = await call_next(request) resp.headers["Content-Security-Policy"] = ( "default-src 'self'; " "script-src 'self' https://cdn.jsdelivr.net; " "style-src 'self'; " "frame-ancestors 'none'" ) return resp
Report-Only 모드: 헤더 이름을 Content-Security-Policy-Report-Only로 바꾸면 위반을 차단하지 않고 콘솔·report-uri로만 보고합니다. 운영 배포 전, 실제로 뭐가 걸리는지 먼저 관찰할 때 씁니다.