stack-analysis
CHAPTER 104 / 120
읽기 약 2분
FUNCTION
CSP(Content Security Policy) 완벽 설정
핵심 개념
CSP 디렉티브·nonce·report-uri·실전 정책 — XSS 95% 방어.
본문
CSP 기본 디렉티브
default-src 'self' # 모든 리소스 기본값
script-src 'self' # JS 출처
style-src 'self' 'unsafe-inline' # CSS 출처
img-src 'self' data: https: # 이미지
font-src 'self' # 폰트
connect-src 'self' wss: # XHR·WebSocket
frame-src 'none' # iframe
object-src 'none' # plugin (deprecated)
base-uri 'self' # base 태그
form-action 'self' # form 제출 대상
frame-ancestors 'none' # 부모 frame (clickjacking)
upgrade-insecure-requests # http → https 자동Next.js CSP 적용
// next.config.js
const ContentSecurityPolicy = `
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline' https://www.googletagmanager.com https://www.google-analytics.com;
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data: https:;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://www.google-analytics.com https://api.example.com wss://realtime.example.com;
frame-src 'self' https://www.youtube.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests;
`.replace(/\s{2,}/g, ' ').trim();
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [
{ key: 'Content-Security-Policy', value: ContentSecurityPolicy },
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
],
}];
},
};Nonce — 인라인 스크립트 안전하게
// middleware.ts
import { NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
const csp = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
style-src 'self' 'unsafe-inline';
`.replace(/\s{2,}/g, ' ').trim();
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-nonce', nonce);
const response = NextResponse.next({ request: { headers: requestHeaders } });
response.headers.set('Content-Security-Policy', csp);
return response;
}
// app/layout.tsx
import { headers } from 'next/headers';
export default async function RootLayout({ children }) {
const nonce = (await headers()).get('x-nonce');
return (
<html>
<head>
<Script id="ga" nonce={nonce}>{`
// 인라인 스크립트 안전
`}</Script>
</head>
<body>{children}</body>
</html>
);
}CSP Report-Only (먼저 모니터링)
headers: [{
key: 'Content-Security-Policy-Report-Only',
value: `${ContentSecurityPolicy}; report-to csp-endpoint`,
}, {
key: 'Reporting-Endpoints',
value: 'csp-endpoint="/api/csp-report"',
}]
// API
app.post('/api/csp-report', async (req, res) => {
const report = req.body;
await db.cspViolation.create({
data: {
blockedUri: report['blocked-uri'],
violatedDirective: report['violated-directive'],
sourceFile: report['source-file'],
lineNumber: report['line-number'],
ip: req.ip,
},
});
res.status(204).end();
});
// → 1주일 모니터 → 정책 조정 → enforce 모드 전환일반적인 CSP 함정
1. 'unsafe-inline' 남발
→ nonce/hash로 점진 제거
2. 'unsafe-eval' 필요
→ modern build로 제거 (eval 안 쓰는 라이브러리)
3. data: URI 너무 광범위
→ 이미지만 허용, 스크립트 차단
4. * (any) 사용
→ 명시적 화이트리스트
5. localhost 개발 vs 프로덕션 분리
const csp = process.env.NODE_ENV === 'production'
? STRICT_CSP
: DEV_CSP;추가 보안 헤더
{
// Clickjacking 방어
key: 'X-Frame-Options', value: 'DENY',
// MIME type sniffing 방어
key: 'X-Content-Type-Options', value: 'nosniff',
// Referrer 정보 제한
key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin',
// 권한 정책 (Camera·Microphone 등)
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(self), payment=()',
// CORP (Cross-Origin Resource Policy)
key: 'Cross-Origin-Resource-Policy', value: 'same-origin',
// COOP (Cross-Origin Opener Policy)
key: 'Cross-Origin-Opener-Policy', value: 'same-origin',
}검증 도구
1. SecurityHeaders.com
- 헤더 점수 (A+ 목표)
2. Mozilla Observatory
- https://observatory.mozilla.org
3. CSP Evaluator (Google)
- https://csp-evaluator.withgoogle.com
4. report-uri.com
- CSP 위반 수집·시각화다음 챕터
CH.105 "SQL Injection 방어".
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 코드의 CSP 보안 부분을 분석해서 실전 분석 + 개선 우선순위를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
CSP 보안 관련 베스트 프랙티스 5가지를 비교 분석해서 패턴 추출를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 프로젝트 전체에서 CSP 보안 최적화 가능 위치를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 시장의 CSP 보안 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
CSP(Content Security Policy) 완벽 설정은 이 3가지만 확실히 잡으세요
1.CSP는 XSS 95% 방어 — Report-Only로 1주 모니터 후 enforce
2.nonce + strict-dynamic = 인라인 스크립트 안전
3.추가 헤더 (X-Frame, Permissions-Policy 등) 7종 필수
공유하기
진행도 104 / 120