Skip to content

[ Core ] 권한 응답이 400 으로 뭉개지고 개인 목록·동기화 경로가 공개로 선언돼 있다 #101

Description

@RosieOh

💚 어떤 기능인가요?

전수 점검에서 함께 나온 세 가지. #100 과 같은 PR 로 해소한다.

1. BusinessException 이 언제나 400 으로 나간다

전역 핸들러가 ErrorCode 를 INVALID_INPUT 으로, 상태를 400 으로 못 박고 있다.

ErrorResponse.of(ErrorCode.INVALID_INPUT, ...) // ex.getErrorCode() 를 버린다
.status(HttpStatus.BAD_REQUEST) // ex.getHttpStatus() 를 버린다

BusinessExceptionCareCodeException 의 하위 타입이라 자기 ErrorCode 와 HttpStatus 를
이미 들고 있다.

영향이 큰 쪽은 인증이다. 프런트 인터셉터는 401 에서만 토큰을 갱신하고 로그인으로
보낸다(src/apis/interceptor.ts). 세션 만료가 400 으로 나가면 갱신도 재로그인도
일어나지 않고 "입력값이 유효하지 않습니다" 만 보인다.

해당 경로 9곳: HealthService 6, NotificationService 2, JwtService 1.

2. 고정 경로가 앞선 와일드카드에 먹혀 공개로 선언돼 있다

경로먹히는 규칙성격
GET /health/hospitals/likes/health/hospitals/*내가 찜한 병원
GET /community/posts/liked/community/posts/*내가 좋아요한 글
GET /community/posts/bookmarked/community/posts/*내가 북마크한 글

한 세그먼트라 상세 조회 와일드카드와 모양이 같아 눈에 띄지 않는다.
지금은 컨트롤러가 현재 사용자를 다시 확인해 401 을 내지만, 나중에 userId 파라미터를
받도록 바뀌면 그대로 남의 목록이 열린다. 이 저장소는 같은 유형으로 이미 한 번 사고가
났다(/health/**/hospitals/** 를 삼켜 공개 API 가 통째로 막힘).

3. 공공데이터 동기화가 비로그인으로 실행된다

POST /api/public/care-facilities/sync-all
GET /api/public/care-facilities/swagger/sync

/api/public/care-facilities/** 가 통째로 permitAll 이라 그 아래 동기화 트리거까지 열려 있다.
외부 공공데이터 API 를 페이지 단위로 호출하고 DB 에 쓴다. 누구나 일일 한도를 태우고
DB 를 두드릴 수 있다. 이 프로젝트는 "공공데이터 한도 초과"를 운영 알림으로 잡는데,
그 상황을 외부에서 마음대로 만들 수 있다.

swagger/sync 는 GET 이라 브라우저 접속이나 크롤러만으로도 실행된다.

같은 기능이 POST /api/admin/public-data/facilities/sync 로 이미 있다.

✅ To Dos

  • 핸들러가 ex.getErrorCode() / ex.getHttpStatus() 를 쓰도록
  • 개인 목록 경로를 와일드카드보다 앞에 선언
  • 동기화 트리거를 ADMIN 으로 제한 (조회는 공개 유지)
  • 접근제어 계약 테스트에 실제 응답 코드로 고정

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions