Kiwi Office는 문서와 계정을 안전하게 보호하기 위해 아래 통제를 운영합니다. 이 문서는 실제 구현 기준이며, 코드 저장소의 docs/SECURITY.md와 함께 유지됩니다.
1. 인증과 계정
- 비밀번호는 단방향 해시(scrypt 기반)로 저장하며 평문을 저장하지 않습니다.
- 이메일 인증을 완료해야 로그인할 수 있고, 비밀번호 재설정 시 모든 세션을 무효화합니다.
- 비밀번호 변경 시 다른 기기의 세션을 모두 종료합니다.
- 세션은 서버 저장·회전되며 30일 후 만료됩니다. 의심스러운 세션은 관리자에게 즉시 종료를 요청할 수 있습니다.
- TOTP 2단계 인증과 일회용 백업 코드를 지원하며, 관리자는 분실 시 2단계 인증을 초기화할 수 있습니다.
- 가입·로그인·비밀번호 재설정에 속도 제한(분당/시간당)과 선택적 Cloudflare Turnstile을 적용합니다.
- 관리자 계정은 운영 환경에서 2단계 인증이 강제되며, 인증을 설정하기 전에는 관리자 콘솔과 관리자 API에 접근할 수 없습니다.
2. 애플리케이션 보안
- 엄격한 CSP(요청별 nonce + strict-dynamic), HSTS, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, frame-ancestors 'none'을 모든 응답에 적용합니다.
- 상태 변경 API는 Origin 검사 + SameSite=Lax 쿠키로 CSRF를 방어합니다.
- 모든 입력은 서버에서 스키마 검증(zod)하며, 업로드는 매직바이트 검사로 위장 파일을 차단합니다.
- DOCX/HTML 가져오기 결과는 허용 태그·속성만 남기는 새니타이저를 통과합니다.
- 문서 접근은 소유자 → 협업자 → 링크 토큰 순으로 매 요청 재검증합니다.
- 업로드 파일은 비공개이며 인증·권한 확인 후에만 스트리밍됩니다. SVG는 별도 CSP로 격리합니다.
3. 데이터 보호
- 인터넷 구간은 TLS 1.3(가능한 클라이언트에는 X25519MLKEM768 하이브리드 양자내성 키 교환)으로 보호합니다.
- 문서 본문과 업로드 파일은 애플리케이션에서 AES-256-GCM으로 암호화한 뒤 PostgreSQL·객체 저장소에 기록합니다. S3를 사용하는 경우 SSE-AES256이 추가로 적용됩니다.
- 운영 환경에서는 암호화 키를 환경 비밀 저장소/KMS에 보관하고, 이전 키를 통한 무중단 회전을 지원합니다.
- 운영 환경에서는 데이터베이스를 사설 네트워크에 두고 공개 인터넷에서 직접 접근할 수 없게 구성합니다.
- 운영 배포 시 백업을 age 공개키로 암호화해 오프사이트에 보관하고, 정기적으로 복구 훈련을 수행합니다.
- 현재 유료 결제를 운영하지 않으므로 카드 정보나 청구 정보를 수집하지 않습니다. 결제 도입 시 Stripe가 카드 정보를 처리하며, 운영자는 카드 번호를 저장하지 않습니다.
- 서버·데이터베이스 호스팅 제공자: 가비아
4. 관측과 대응
- 구조화 로그(pino)에 비밀번호·토큰·쿠키가 자동 마스킹되어 기록됩니다.
- 감사 로그: 로그인, 문서 생성/수정/삭제, 공유, 내보내기, 관리자 행위를 기록합니다.
- 헬스체크(/api/health)와 운영 지표(/api/metrics, 토큰 보호)를 모니터링 시스템과 연동할 수 있습니다.
- 보안 사고 대응 절차와 연락 체계는 운영 런북에 정의되어 있으며, 침해 시 72시간 내 통지합니다.
5. 취약점 신고
보안 취약점을 발견하면 contact@manuai.co.kr로 알려주세요. 48시간 내 확인하고, 재현 절차를 제공해 주시면 수정 일정을 안내합니다. 선의의 제보에 대해서는 법적 조치를 취하지 않습니다.
6. 운영 체크리스트 (요약)
- 의존성 취약점 스캔: CI에서
npm audit --omit=dev통과 필요 - 시크릿 관리: 환경 변수/시크릿 매니저만 사용, 저장소 커밋 금지
- 배포: 이미지 서명·취약점 스캔 후 롤링 배포, 롤백 절차 문서화
- 접근: 운영 DB 접근은 감사 로그가 남는 배스천을 통해서만 허용
