Content Security Policy: nonce와 해시
인라인 스크립트에는 nonce를, 알려진 코드 조각에는 해시를 사용하고, 프로덕션에서 위반을 모니터링하도록 report-uri를 설정한 엄격한 CSP를 작성합니다.
Content Security Policy: nonce와 해시은(는) CoddyKit의 무료 Frontend Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Frontend Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Frontend Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
CSP 복습
CSP는 브라우저가 로드할 수 있는 항목(스크립트, 스타일, 이미지, 글꼴, 프레임, 연결)을 허용 목록으로 지정하는 HTTP 헤더입니다. 심층 방어를 제공하므로 XSS가 필터를 통과하더라도 CSP가 페이로드를 차단하는 경우가 많습니다.
CSP 헤더 구조
각 지시문에는 허용된 소스가 나열됩니다. 'self'는 동일 출처를 의미합니다. 특정 URL도 허용할 수 있습니다.
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
font-src 'self' https://fonts.gstatic.com;
frame-ancestors 'none';
base-uri 'self';일반적인 지시문
default-src: 모든 항목에 대한 대체값입니다. script-src: JavaScript입니다. style-src: CSS입니다. img-src: 이미지입니다. connect-src: fetch/XHR/WebSocket입니다. font-src: 글꼴입니다. frame-ancestors: 사용자의 사이트를 iframe으로 포함할 수 있는 사이트를 지정합니다(클릭재킹 방지).
'unsafe-inline' — 흔한 허점
많은 사이트가 인라인 <script> 태그와 onclick 속성을 허용하기 위해 'unsafe-inline'을 추가합니다. 이렇게 하면 CSP의 주된 목적이 무력화되어 XSS 페이로드가 인라인으로 실행될 수 있습니다. 논스나 해시로 대체하십시오.
논스 — 일회성 허용 목록
요청마다 무작위 논스를 생성하십시오. 정상적인 인라인 스크립트에 논스를 지정하십시오. 브라우저는 일치하는 논스가 있는 스크립트만 허용합니다.
// Server (Express middleware):
import crypto from 'crypto';
app.use((req, res, next) => {
res.locals.nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy',
`script-src 'nonce-${res.locals.nonce}' 'strict-dynamic'`
);
next();
});
// Template:
<script nonce="<%= nonce %>">window.config = {...};</script>'strict-dynamic'
논스를 'strict-dynamic'과 함께 사용하십시오. 논스가 있는 신뢰된 스크립트는 추가 스크립트를 불러올 수 있습니다. 따라서 모든 스크립트 소스 URL을 나열할 필요가 없습니다. 현재 CSP의 모범 사례입니다.
해시 — 정적 허용 목록
변경되지 않는 것으로 알려진 인라인 스크립트(예: 빌드할 때마다 동일한 부트스트랩 코드 조각을 출력하는 경우)는 SHA-256을 계산하여 해시 소스로 추가하십시오. 요청마다 논스를 생성할 필요가 없습니다.
// Hash of: console.log('hi');
Content-Security-Policy: script-src 'sha256-XwCNuB+/RUgPlAACI+yHrUKqUsm4zlpGV/Q8tEUx0Q4='인라인 스타일 해시
인라인 <style> 태그에도 같은 방법을 사용할 수 있습니다. 해시를 계산하여 style-src에 추가하십시오. CSS에서는 'unsafe-inline'보다 안전합니다.
CSP 보고 모드
Content-Security-Policy-Report-Only를 사용하면 정책을 적용하지 않고 테스트할 수 있습니다. 위반 사항은 엔드포인트로 보고되지만 아무것도 차단하지 않습니다. CSP를 점진적으로 도입할 때 유용합니다.
Content-Security-Policy-Report-Only:
default-src 'self';
report-uri /csp-violations
// /csp-violations receives POSTs like:
{
"csp-report": {
"document-uri": "https://example.com/",
"violated-directive": "script-src 'self'",
"blocked-uri": "https://evil.com/x.js"
}
}report-to(최신 방식)
report-to + Reporting-Endpoints는 report-uri를 대체하는 최신 방식입니다. 동일한 데이터를 더 구조화된 형태로 전달합니다.
Reporting-Endpoints: csp="/csp-reports"
Content-Security-Policy: script-src 'self'; report-to csp프레임워크 통합
Next.js: middleware.ts 또는 next.config.js 헤더를 통해 CSP를 설정합니다. Nuxt: nuxt-security 모듈을 사용합니다. Vite: 개발 서버 헤더를 구성하고, 프로덕션에서는 호스트(Vercel, Netlify)의 헤더 설정을 사용합니다.
// next.config.js
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'strict-dynamic'"
}]
}];
}
};CSP 테스트
DevTools → 콘솔을 여십시오. CSP 위반 사항이 이곳에 로그로 기록됩니다. https://csp-evaluator.withgoogle.com/을 사용하여 정책을 평가하십시오. 먼저 프로덕션에서 보고 전용 모드를 사용하고, 모든 위반 사항을 수정한 후 적용하십시오.
빠른 확인
script-src 지시문에 'unsafe-inline'을 사용하는 것이 CSP의 약점으로 간주되는 이유는 무엇입니까?
복습: CSP 모범 사례
리소스 유형별 지시문을 포함한 Content-Security-Policy 헤더를 설정하십시오. 'unsafe-inline'은 피하고 논스 + 'strict-dynamic' 또는 SHA 해시를 사용하십시오. frame-ancestors 'none'(또는 'self')을 설정하십시오. 먼저 보고 전용 모드에서 테스트하십시오. 위반 사항을 /csp-violations로 전송하거나 최신 report-to를 사용하십시오. 프레임워크는 미들웨어 또는 설정 헤더를 통해 CSP를 지원합니다.
자주 묻는 질문
“Content Security Policy: nonce와 해시” 강의는 무료인가요?
네 — “Content Security Policy: nonce와 해시” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Frontend Academy 강의 전체를 잠금 해제할 수 있습니다. Frontend Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“Content Security Policy: nonce와 해시”에서 뭘 배우나요?
인라인 스크립트에는 nonce를, 알려진 코드 조각에는 해시를 사용하고, 프로덕션에서 위반을 모니터링하도록 report-uri를 설정한 엄격한 CSP를 작성합니다. 브라우저에서 직접 실행하는 실습 코드로 Frontend Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Frontend Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Frontend Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“Content Security Policy: nonce와 해시” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Frontend Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Frontend Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- XSS 방지: 출력 인코딩과 CSP
- CSRF: SameSite 쿠키와 토큰
- Content Security Policy: nonce와 해시
- 프런트엔드에서 OAuth 흐름 구현