Files
Hyungi Ahn 12367dd3a1 fix(security): 전체 서비스 보안 점검 — XSS·인가·토큰·헤더·에러마스킹 일괄 수정
Phase 1 CRITICAL XSS:
- marked.parse() → DOMPurify.sanitize() (system3 ai-assistant, issues-management)
- toast innerHTML에 escapeHtml 적용 (system1 api-base, system3 common-header)
- onclick 핸들러 → data 속성 + addEventListener (system2 issue-detail)

Phase 2 HIGH 인가:
- getUserBalance 본인확인 추가 (tksupport vacationController)

Phase 3 HIGH 토큰+CSP:
- localStorage 토큰 저장 제거 — 쿠키 전용 (7개 서비스)
- unsafe-eval CSP 제거 (system1 security.js)

Phase 4 MEDIUM:
- nginx 보안 헤더 추가 (8개 서비스)
- 500 에러 메시지 마스킹 (5개 API)
- path traversal 방지 (system3 file_service.py)
- cookie fallback 데드코드 제거 (4개 auth.js)
- /login/form rate limiting 추가 (sso-auth)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 19:50:00 +09:00

102 lines
1.9 KiB
JavaScript

/**
* 보안 설정 (Helmet)
*
* HTTP 헤더 보안 설정
*
* @author TK-FB-Project
* @since 2025-12-11
*/
/**
* Helmet 보안 설정 옵션
*/
const helmetOptions = {
/**
* Content Security Policy
* XSS 공격 방지
*/
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
scriptSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:", "blob:"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
connectSrc: ["'self'", "https://api.technicalkorea.com"],
frameSrc: ["'none'"],
objectSrc: ["'none'"]
}
},
/**
* HTTP Strict Transport Security (HSTS)
* HTTPS 강제 사용
*/
hsts: {
maxAge: 31536000, // 1년
includeSubDomains: true,
preload: true
},
/**
* X-Frame-Options
* 클릭재킹 공격 방지
*/
frameguard: {
action: 'deny'
},
/**
* X-Content-Type-Options
* MIME 타입 스니핑 방지
*/
noSniff: true,
/**
* X-XSS-Protection
* XSS 필터 활성화
*/
xssFilter: true,
/**
* Referrer-Policy
* 리퍼러 정보 제어
*/
referrerPolicy: {
policy: 'strict-origin-when-cross-origin'
},
/**
* X-DNS-Prefetch-Control
* DNS prefetching 제어
*/
dnsPrefetchControl: {
allow: false
},
/**
* X-Download-Options
* IE8+ 다운로드 옵션
*/
ieNoOpen: true,
/**
* X-Permitted-Cross-Domain-Policies
* Adobe 제품의 크로스 도메인 정책
*/
permittedCrossDomainPolicies: {
permittedPolicies: 'none'
},
/**
* Cross-Origin-Resource-Policy
* 크로스 오리진 리소스 공유 설정
* 이미지 등 정적 파일을 다른 포트에서 로드할 수 있도록 허용
*/
crossOriginResourcePolicy: {
policy: 'cross-origin'
}
};
module.exports = helmetOptions;