전 영역 보안 보완 이행 점검 결과 (하편: 4-1 ~ 8-1)
목차 5개 단원
서론
"이전 #26 일지에 이어 여행 플랫폼 '온데(Onde)' 실서버 환경의 첫 웹/API 보안 취약점 이행 점검 하편 결과를 정리합니다. 이번 하편에서는 토큰 인증값 검증, 쿠키 세션 하이재킹 방지, 접근 제어 소유권 매핑, 전체 인프라 컨테이너 설정까지 여러 통제 계층이 얽혀 있어 패킷 분석과 설정 조정이 쉽지 않았습니다. 여러 예외 처리 문제를 해결한 뒤 4-1 쿠키 조작 위험부터 8-1 미정의 인프라 보완까지 모든 항목을 '이행 완료'로 판단한 백엔드 내용을 공유하며, 이후 전체 보완 조치 뒤 최종 재검증을 진행할 예정입니다."
이행 점검 하편에서는 4-1 쿠키·세션 통제부터 8-1 인프라 보완까지 남은 항목의 조치와 동적 검증 결과를 정리합니다.
1. 취약한 인증 및 세션 관리 영역 (4-1 ~ 4-5)
── 4-1. 쿠키(Cookie) 및 웹 스토리지 조작 가능성 (일반 - 이행완료)
- 보완 조치: 기존 로그인 성공 시 백엔드가 응답 JSON 바디와 프론트엔드 일반 쿠키에 액세스 토큰 문자열을 노출해 XSS 공격 시
HttpOnly방어를 우회할 수 있던 심각한 구조 문제를 고쳤습니다. 로그인, 관리자 로그인, 토큰 재발급을 포함한 전체 인증 API의 반환 객체LoginResponse에서accessToken과refreshToken필드를 삭제했습니다. - 동적 검증: 중요 인증 토큰은 서버의
AuthCookieSupport모듈을 통해 브라우저가 관리하는 보안 속성 헤더로만 전송하고HttpOnly,Secure,SameSite=Lax속성을 적용했습니다. 프론트엔드도 자바스크립트로 세션 컨텍스트를 조작하던 기존 로직을 없애 토큰 탈취 위험을 막았습니다.
── 4-2. 인증(세션 및 토큰) 값 안전성 설정 여부 (일반 - 이행완료)
- 문제점: 인증 세션 정보 노출 및 만료/중복 로그인 통제가 풀린 오설정이 식별되었습니다.
- 대표 Case 1 (중요 인증 정보의 클라이언트 노출): 응답 객체 내 순차 회원 일련번호(
memberId: 1) 표출 필드를 소멸시키고, JWT Payload 영역의sub인자 내부에 기재되던 고유 사용자 로그인 이메일을 DB 내 가입자 고유 매핑 UUID 값인auth_subject_id규격으로 치환하여 개인 식별정보를 안전하게 비식별화 완료했습니다. - Case 2 (로그아웃 시 서버 측 세션 즉시 미파기): 백엔드에
POST /api/v1/auth/logout세션 종료 API를 추가했습니다. 요청을 받으면AuthTokenBlacklistService가 Access Token JTI를 Redis 블랙리스트에 등록하고 DB의 Refresh Token 레코드를 삭제해 만료 전 토큰 재사용을 막습니다. - Case 3 (동일 계정에 대한 다중 중복 로그인 통제 부재): 토큰 발급 시 접속 IP 및
User-Agent해시 식별자 명세를 복합 추출하여RefreshToken영속화 계층에 강력하게 상호 바인딩(AuthClientContext) 처리했습니다.JwtAuthenticationFilter보안 터널 통과 시 환경 불일치가 감지되면 인증을 거부하며, 신규 로그인 성공 시 구 세션 토큰을 필수 블랙리스트 적재 시켜 중복 로그인을 차단합니다.
- 대표 Case 1 (중요 인증 정보의 클라이언트 노출): 응답 객체 내 순차 회원 일련번호(
── 4-3. 접근제어 우회 가능성 확인 (일반 - 이행완료)
- 문제점: 비즈니스 인가 아키텍처 내에서 요청 파라미터 값과 현재 API 요청을 보낸 보안 컨텍스트 간의 소유권 상호 대조 검증 로직이 전무하여 타인의 자산을 무단 제어하는 심각한 IDOR 결함 케이스가 도출되었습니다.
- 대표 Case 1 (예약 요청 회원 식별자 파라미터 조작 명의 도용): 숙소/렌터카 예약 등록 패킷 바디 내의
memberId값을 본인 번호 대신 임의의 타인 회원 번호로 변조 송신할 시, 서버가 소유주 대조를 안 하던 결함을 리팩토링하여 회원 식별 처리를 파라미터가 아닌 JWT 인증 세션 내부 객체(@LoginMember) 단에서만 추출되도록 전향했습니다. 인위적인 타인 memberId 변수 추가 오염 패킷 인입 시MemberIdBindingValidator검증기가 작동하여 HTTP 403 Forbidden 코드로 접근권을 즉각 상실 차단시킵니다. - Case 2 (매물 식별 파라미터 조작 상품 정보 무단 변조 - BOLA): 파트너 셀러가 실시간 요금 및 방 재고를 관리하는 캘린더 PATCH API 처리 단초 직전 계층에
SellerPropertyOwnershipService.assertSellerOwnsProperty크로스 체크 소유권 검증 인가 모듈을 앞에 배치하여 불일치 시 HTTP 403으로 수정을 거부하도록 조치했습니다.
- 대표 Case 1 (예약 요청 회원 식별자 파라미터 조작 명의 도용): 숙소/렌터카 예약 등록 패킷 바디 내의
── 4-4 ~ 4-5. 비인증 주소 진입 및 일반계정 권한 상승 통제 점검 (일반 - 양호/완료)
- 4-4. 비인증 상태로 중요 page접근 가능성 (양호): 프론트엔드 라우터 계층 가드 모듈인
<RequireAuth>핵심 컴포넌트를 통해 비인증 다이렉트 URL 타이핑 진입 시 즉각 로그인 바운스 차단 처리가 작동하며 백엔드 시큐리티 연동 통제 역시 양호한 상태를 상시 유지 중입니다. - 4-5. 일반계정 권한 상승 가능성 (이행완료): 가입 요청 패킷의 Body 데이터를 검증 없이 영속화 계층에 매핑하여
"role": "SUPER_ADMIN"등의 권한 코드를 가로채 기입 시 최고 관리자로 바로 승인 가입되던 심각한 결함을 고쳤습니다. 백엔드 내에SignupRolePolicy통제 로직을 넣어 신규 가입 시 수용 허용 역할을 오직 일반 회원(USER) 및 일반 파트너(SELLER) 화이트리스트 규격 대역으로만 제한하고, 이외의 등급 코드가 전달되면ForbiddenException(HTTP 403) 예외를 발생시켜 가입을 기술적으로 막았습니다.
2. 중요 정보 저장/전송 처리 미흡 & 부적절한 오류 처리 영역 (5-1 ~ 6-2)
── 5-1. 소스코드 내 주요정보 노출 여부 (일반 - 이행완료)
- 보완 조치: 인프라 환경 변수 주입이 실패할 경우 소스코드 내부에 하드코딩 기재된 디폴트 문자열 상수로 자동 우회 구동되던 유해 패턴인
AdminJwtTokenProvider.java와AesUtil.java내부 콜론(:) 기본값 상수를 영구 삭제 처리했습니다. - 동적 검증: 백엔드에
RequiredSecretValidator를 연결해 시스템 시작 단계에서JWT_SECRET과AES_SECRET_KEY가 비어 있거나 형식에 맞지 않으면, 컨테이너 초기화 중IllegalStateException이 발생해 실행되지 않도록 Fail-Fast 방식으로 바꿨습니다.
── 5-2 & 3-3. 요청 및 응답 값 내 주요정보 포함여부 확인 (중요 - 이행완료)
- 보완 조치: 개인정보 프로필 및 판매자 정산 대시보드 API 통신 트래픽 패킷 분석 결과 당사자 응답이라는 명목하에 이메일명, 성명, 연락처, 정산 은행 및 민감 계좌 데이터가 평문 노출되던 결함을 조치하기 위해 응답 DTO 직렬화 계층 전방 단에
PersonalDataMasker비식별화 필터 엔진을 탑재해 정보 은닉 가드를 적용했습니다. - 동적 검증: 실제 조회 결과에서 이메일, 성명, 휴대폰, 은행 계좌 정보 일부가 마스킹되어 나오는 것을 확인했습니다. 화면에서 원문 데이터를 확인하거나 수정해야 할 때는 별도 reveal API를 거쳐
SensitiveRevealAuthService의 2차 비밀번호 확인(2FA)을 통과한 세션에만 원문 데이터를 반환하도록 했습니다.
── 6-1. 오류페이지를 통한 정보 노출 여부 (일반 - 이행완료)
- 보완 조치: 비정상적 데이터 입력 시 내부 개발 프레임워크 런타임 최상위 예외 클래스 명칭 및 상세 예외 파싱 스택트레이스 구문이
systemMessage인자에 노출되던 결함 메커니즘을 글로벌 에러 제어기(@RestControllerAdvice) 구조 정비를 통해 차단했습니다. - 동적 검증: 입력값 크기와 자료형 형식 오류가 발생하면 외부 응답에는 "요청 형식이 올바르지 않습니다." 또는 "서버 내부 오류가 발생했습니다." 같은 표준 안내 문구만 반환하도록 했습니다. 상세 스택 트레이스는 외부에 반환하지 않고 서버 내부 보안 로그 파일(
.log)에만 기록되는 것을 확인했습니다. 프론트엔드 Toast 알림도 원시 에러 메시지 대신 정해진 안내 메시지를 보여 주도록 수정했습니다.
── 6-2. 일괄적인 오류 처리 페이지 존재 여부 (일반 - 양호)
- 진단 결과: 사용자 및 관리자 로그인 실패 처리 에러 분기를 점검한 결과, DB에 미등록된 가짜 이메일 주소를 입력하든 혹은 등록 계정이되 패스워드가 오염된 인자를 던지든 상관없이 동일한 포맷의
HTTP 401 Unauthorized상태 코드와 "인증에 실패하였습니다." 일괄 고정 평문 메시지를 상호 균등 배출하여 외부 공격자가 계정 실존 여부를 무차별 열거 수집해 갈 수 없도록 안전 통제 중임을 확인했습니다.
3. 취약한 컴포넌트 구성요소 & 기타 인프라 보안 (7-1 ~ 8-1)
── 7-1 ~ 7-2. 위험 메소드 제어 및 파일 목록화 차단 검증 (일반 - 양호)
- 진단 결과: 인프라 통제 게이트웨이 사양을 검증하기 위해 크로스 사이트 트래킹 무기가 되는 위험 메소드
TRACE패킷 접근을 curl로 위조 인입시킨 결과 앞단 로드밸런서 계층에서 요청 커넥션을 드롭시키며 HTTP 405 Not Allowed 에러로 안전하게 진입을 막고 있음을 실증했습니다. 정적 자원 디렉터리 경로인/assets/패널 직접 조회 시에도 Nginx 엔진의autoindex off;글로벌 환경 구성 설정이 견고하게 작동하여 하위 파일 리스팅을 거부하고 HTTP 403 Forbidden 코드를 엄격히 배출 중입니다.
── 7-3. 서버 헤더정보 노출 (일반 - 이행완료)
- 보완 조치: 정상 데이터 통신과 오류 발생 시 HTTP Response Header의
Server필드에 웹 서버 엔진의 상세 버전이 그대로 노출되던 설정을 고쳤습니다. - 동적 검증: OpenResty(Nginx) 설정에
server_tokens off;옵션을 적용해 버전 정보 노출을 1차 숨김 처리하고,headers-more-nginx-module확장 엔진 설정을 추가 바인딩하여more_clear_headers Server및more_set_headers 'Server: WebServer'필터 옵션을 명시하여 오직Server: WebServer더미 문자열 가상 텍스트로만 강력하게 마스킹 오염 변경되어 출력됨을 최종 검증했습니다.
── 7-4. 취약한 보안설정 (일반 - 이행완료)
- 보완 조치: 교차 출처 리소스 공유 정책 코드인
WebConfig.java에서 모든 외부 도메인의 접근을 허용하던 위험한 와일드카드 설정.allowedOriginPatterns("*")을 삭제했습니다. CORS 접근 정책은 Properties와 SecurityConfig의 한 허용 모듈에서 관리하도록 정리했습니다. - 동적 검증: 운영 환경에서는
https://*.onde.click만 허용하고 전체 와일드카드는 시작 시 거부하도록 했습니다. Burp Suite로 비인가 Origin 헤더를 넣어 호출한 결과, 백엔드에서 HTTP 403 Invalid CORS request로 막히는 것을 확인했습니다.
── 8-1. 취약점 진단 항목에 정의되지 않은 취약점 (일반 - 이행완료)
- Case 1 (내부 캐시 저장소 Redis 패스워드 미인증 연결 정리 결함): 내부망
docker/redis/redis.conf내부 구성에protected-mode yes및requirepass비밀번호 인증 규격을 활성화하고 Spring Bootapplication.yml파라미터 단에 연동 암호를 의무 지정했습니다. 이를 통해 동일 서브넷 내부망 권한을 우회 탈취한 비인가자가 접근하더라도 비밀번호 자격증명 없이는NOAUTH오류를 배출하며 무인증 접근을 차단함을 확인했습니다. - Case 2 (Spring Boot Actuator 엔드포인트 활성화 구조 노출): 내부 인프라 설정과 DB 스키마 마이그레이션 이력이 외부에 노출될 수 있던 Actuator 설정을 고치기 위해,
application.yml에management.endpoints.enabled-by-default: false를 선언하고 웹 노출 범위를 헬스 체크(health) 한 항목으로만 제한했습니다. 외부에서 비즈니스 외 엔드포인트에 접근하면 403/404 또는 index 리다이렉트가 반환되고 민감 정보가 나오지 않는 것을 확인했습니다.
5. 결론 및 다음 단계: 하편 이행 점검 마무리와 관리자 영역 재검증
#26 상편(1-1 ~ 3-6)에 이어, 이번 하편에서는 4-1 ~ 8-1 구간의 보완과 동적 검증까지 마쳤습니다. 대표적으로는 토큰을 Body가 아닌 HttpOnly 쿠키로만 내리기, CORS 와일드카드 제거, Redis requirepass·Actuator 노출 축소, 에러 스택 마스킹 같은 조치가 실제로 막히는 것까지 확인했습니다. 일반·판매자 영역 이행 점검은 여기까지 정리했고, 다음으로는 관리자 백오피스 쪽 이행 결과와 남은 재검증을 이어서 적습니다.
- Next 마일스톤 계획:
- 관리자 백오피스 이행 점검 정리: admin 도메인에서 조치한 항목을 같은 가이드라인 형식으로 요약합니다.
- 최종 재검증: 패치가 실제로 막혔는지 패킷·설정 기준으로 한 번 더 확인한 뒤, 자동 진단 플랫폼(아르고스) 구축으로 넘어갑니다.
수동 진단 · 이행 점검단계 3 · Day 15–28 · 13 / 14일지 전체 →
- Day 15아르고스(Argus) 명칭·A/B/C 분담, 5개 설계 산출물 및 7월 개발 일정 수립
- Day 16WEB/API 취약점 진단 및 모의침투(Penetration Testing) 기록
- Day 17온데 실서버 배포와 2차 멘토링용 질문 정리
- Day 18두번째 멘토링
- Day 19온데(Onde) 멘토링 피드백 반영 및 아르고스(Argus) 모듈 별 1인 개발 파이프라인 개발
- Day 20아르고스 3주 일정 확정과 온데 DAST 가능성 평가
- Day 21웹/API 보안 취약점 진단 상세 결과 및 초보 진단자의 시행착오
- Day 22웹/API 최초 취약점 진단 결과보고서 — 파라미터 검증과 파일 처리
- Day 23중간 발표 PPT 작성
- Day 24실전 모의침투 보안 진단 보고서 — 3-2 ~ 8-1 항목
- Day 25관리자 백오피스 수동 보안 진단 결과보고서
- Day 26전 영역 보안 보완 이행 점검 결과 (상편: 1-1 ~ 3-6)
- Day 27전 영역 보안 보완 이행 점검 결과 (하편: 4-1 ~ 8-1)
- Day 28관리자 백오피스 이행 점검 완료 및 Argus 착수