Skip to content

feat: 보안 보강 1차 + 식당·메뉴 대량 등록 + 지도·메뉴 UI 개편 + EC2 운영 적용 준비#34

Merged
chlwjddls0923 merged 9 commits into
mainfrom
choi
May 22, 2026
Merged

feat: 보안 보강 1차 + 식당·메뉴 대량 등록 + 지도·메뉴 UI 개편 + EC2 운영 적용 준비#34
chlwjddls0923 merged 9 commits into
mainfrom
choi

Conversation

@chlwjddls0923
Copy link
Copy Markdown
Contributor

@chlwjddls0923 chlwjddls0923 commented May 22, 2026

Summary

  1. 🔒 보안 보강 1차 — 외부 ISMS-P 점검 9건 + 자체 점검 4건 정리

Major changes

🔒 보안 보강 1차 (9 commit)

  • AllExceptionsFilter: 전역 catch, 응답 포맷 통일({code, message, requestId, timestamp, path}), production 스택 차단
  • AppError + 코드 enum + 서브클래스 5종 (NotFoundError/InvalidCredentialsError/ForbiddenError/ConflictError/ExternalDependencyError)
  • Helmet + app.disable("x-powered-by") — 프레임워크 정보 노출 차단 (Nginx proxy_hide_header 와 다중 방어)
  • JWT 만료 7d → 1d 단축 + JWT_EXPIRES_IN env 변수화 (정규식으로 과도값 차단)
  • SensitiveFieldsInterceptor: access 로그 + 비밀번호·토큰·카드번호 등 마스킹 (mask() 정적 메서드)
  • env validation 완화 — AWS_* required → optional (S3 미사용 EC2 단독 배포 대응)
  • Swagger UI production 비공개 (SWAGGER_ENABLED=true 로 토글)
  • 상세: docs/보안_보강_2026-05-22.md (13개 항목 문제·해결·검증 절차)

🛠 빌드·CI

  • packageManager: pnpm@10.33.2 핀 (Dockerfile node:20-alpine 에서 corepack 의 pnpm 11 자동 다운로드 OOM 방지)
  • pnpm/action-setup@v4 의 version 필드 제거 (packageManager 중복)
  • apps/web/types/kakao.d.ts: Map.getBounds / Map.relayout / setLevel anchor / LatLngBounds.getSouthWest·getNorthEast 추가
  • MenuList: Map.values for-of → forEach (downlevelIteration 미설정 환경 대응)

Test plan

  • 보안 검증:
    • 응답 헤더에 x-frame-options, content-security-policy, x-content-type-options, referrer-policy, permissions-policy, strict-transport-security, x-request-id 보임. x-powered-by 안 보임
    • 의도적으로 잘못된 요청 시 응답 body 가 {code, message, requestId, timestamp, path} 포맷
    • production 에서 /api/docs 404 (Swagger 비공개)
    • JWT_EXPIRES_IN env 로 만료 시간 조정 가능
  • CI: lint / build (api+web) / docker-build 전부 통과

운영 환경 적용 절차

이 PR merge 후 docker 브랜치 동기화 + EC2 재배포 필요:

…N/LOG_LEVEL 추가

- AWS_REGION/ACCESS_KEY_ID/SECRET_ACCESS_KEY/S3_BUCKET 모두 required → optional. S3 미사용 환경에서 API 부팅 실패 방지
- JWT_EXPIRES_IN 추가 (1d 기본, 1y 같은 과도값 정규식 차단)
- NODE_ENV / LOG_LEVEL 명시
- CORS_ORIGIN URI 강제 제거 (쉼표 구분 multiple origin 지원)
- 7d 는 토큰 탈취 시 노출 윈도우가 길어 1d 로 단축
- 운영 정책은 .env 의 JWT_EXPIRES_IN 으로 무중단 조정 가능
- AppErrorCode: UNAUTHORIZED/FORBIDDEN/NOT_FOUND/VALIDATION_FAILED/CONFLICT/RATE_LIMITED 등 안정적 식별자
- AppError extends HttpException — code/message/status 한 번에 표현
- 서브클래스 5종 (NotFoundError, InvalidCredentialsError, ForbiddenError, ConflictError, ExternalDependencyError)
- 호출부에서 	hrow new NotFoundError('식당...') 같은 가독성·일관성 확보
- @catch() 인자 없이 전역 catch (HttpException + 예측 못 한 런타임)
- 응답 body 표준화: { code, message, requestId, timestamp, path }
- AppError: code/message/status 그대로
- HttpException: status → code 매핑 (400 → BAD_REQUEST 등)
- 그 외 런타임: production 에선 모호한 메시지 (스택은 서버 로그만)
- Nginx X-Request-ID 헤더 echo → 사용자 신고 시 서버 로그 추적 1:1
- 5xx ERROR / 4xx WARN 레벨 분리
- access 로그 (method/path/elapsedMs/requestId) 자동 출력
- 민감 키워드 (password/token/jwt/secret/apiKey/authorization/cookie/cardNumber/cvv/ssn) lowercase 부분 일치 마스킹
- mask() 정적 메서드 노출 — 다른 로거에서도 재사용 가능
- 깊이 5 까지 재귀, 그 이상은 절단해 폭주 방지
- 본문(body) 자체 응답은 건드리지 않음 (UI 영향 X)
…wered-by 비활성 + Swagger production 비공개

- app.disable('x-powered-by') — Express 프레임워크 정보 노출 차단
- helmet({contentSecurityPolicy:false, crossOriginEmbedderPolicy:false}) — Nginx CSP·카카오맵 SDK 호환
- useGlobalFilters(new AllExceptionsFilter()) — 기존 HttpExceptionFilter 대체
- useGlobalInterceptors(new SensitiveFieldsInterceptor()) — access 로깅 + 마스킹
- Swagger UI: production 에선 SWAGGER_ENABLED=true 일 때만 노출
- NestExpressApplication 제네릭 타입 사용 (app.disable 호출 위해)
- 외부 보안 점검(ISMS-P) 9건 + 자체 점검 4건 항목별 정리
- 각 항목: 문제 / 해결 / 의도 / 검증 명령
- HTTP 보안 헤더 7종 (Nginx) · x-powered-by 차단 (다중 방어) · 에러 응답 정규화 · Rate Limit · JWT 만료 단축 · S3 optional · 민감 로깅 마스킹 · Swagger 비공개 · Request-ID 추적
- 적용 후 검증 체크리스트 + Phase 2/3 남은 작업 + 운영 환경 적용 절차
@chlwjddls0923 chlwjddls0923 merged commit 4363800 into main May 22, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant