전 영역 보안 보완 이행 점검 결과 (상편: 1-1 ~ 3-6)
목차 6개 단원
서론
"이전 첫 취약점 진단에서 확인한 보안 결함을 고치고 안전성을 다시 확인하기 위해, 일반 사용자와 판매자 영역을 대상으로 첫 이행 점검(Re-inspection)을 진행했습니다. 이번 상편 일지에서는 전체 28개 표준 항목 중 절반에 해당하는 1-1 입출력 검증부터 3-6 백업 파일 존재 여부까지의 조치와 동적 패킷 검증 내용을 다룹니다. 공통 필터와 구조를 개선해 보안 문제를 막고 '이행 완료'로 판단한 기술 내용을 요약합니다."
최초 진단에서 확인한 결함을 보완한 뒤 일반 사용자·판매자 영역의 이행 점검을 진행했습니다. 1-1부터 3-6까지의 조치와 검증 내용을 다룹니다.
1. 점검 개요 및 총평
이전에 한 최초 보안 진단에서 나온 취약점들이 제대로 조치됐는지 확인하고, 남은 위험을 줄이기 위해 이행 점검을 했습니다. 코드 분석, 서버 설정 확인, 그리고 Burp Suite로 우회를 시도하는 방식으로 검증했습니다.
검증 결과, 흩어져 있던 비즈니스 로직에 공통 검증 모듈과 전역 예외 처리 체계가 적용된 것을 확인했고, 점검 범위의 모든 항목을 최종 '이행 완료(적합)'으로 판단했습니다.
2. 입/출력 값 검증 부재 영역 (1-1 ~ 1-6)
── 1-1. XSS / CSRF 공격 가능성 (중요 - 이행완료)
- 보완 조치: 기존 소스코드의 문자열 정제 누락으로 생기던 Stored XSS 위험을 막기 위해 백엔드에 Hibernate
PRE_INSERT와PRE_UPDATE전역 리스너를 적용했습니다. JPA 계층에서 저장·수정되는 모든 엔티티의 String 필드가InputSanitizer필터를 거치도록 했습니다. 이로써<script>,<style>태그와 위험 이벤트 핸들러가 저장 전에 제거됩니다. - 동적 검증: 여행기 글쓰기, 댓글, 프로필 수정, 상품 등록, 회원가입 등 전체 API 파라미터에 악성 스크립트 구문을 주입하여 등록 테스트를 수행한 결과, 요청 본문에는 스크립트가 포함되어 전송될 수 있으나 저장 이후에는 악성 코드가 모두 제거된 채 일반 텍스트만 안전하게 반환되어 브라우저 내 실행이 차단됨을 확인했습니다. 본 점검 범위에서 최종 이행 적합 판정을 획득했습니다.
── 1-2. 삽입 (Injection) 공격 가능성 (중요 - 이행완료)
- 보완 조치: 기존 여행기 조회 API(
GET /user-api/api/v1/posts)의status파라미터가 Native SQL 문자열에 직접 연결되어 UNION SELECT 쿼리가 우회 실행되던 구조적 결함을 리팩토링했습니다. 문자열 결합 방식의PostRepositoryCustomImpl을 제거하고, status를PostStatusenum 타입으로 수신한 뒤 JPQL Named Parameter(:status) 매개변수 바인딩 처리를 거치도록 아키텍처를 정형화했습니다. - 동적 검증:
status변수 영역에 UNION SELECT 등의 SQL 인젝션 공격 페이로드를 주입하여 송신한 결과, enum 데이터 형식 전환 단계에서 처음부터 거부되어 비인가 데이터 유출 없이 HTTP 400 에러와 함께 안전하게 차단됨을 확인했습니다.
── 1-3. 파라미터 값 및 히든(hidden) 필드 조작 가능성 (중요 - 이행완료)
- Case 1 (결제 요청 금액 변조 우회 결제): 항공권 예약 등록 API 호출 시 클라이언트가 던지는
totalPrice인자를 서버가 그대로 수용하던 논리적 결함을 차단했습니다. 백엔드FlightService.bookSeat()로직 내부에서 좌석 재고의basePrice정가 정보와 승객 수를 곱해 결제 단가를 서버 단에서 직접 계산하도록 변경하고, 일치하지 않으면ValidationException예외로 요청을 즉각 거부하도록 조치했습니다. 임의의 낮은 금액(10원) 변조 패킷 송신 시 즉각 HTTP 400 오류를 배출하며 거래 생성을 반려합니다. - Case 2 (음수 마일리지 파라미터 조작): 결제 사전 등록 DTO 객체 내부의
usedMileage필드에@Min(0)및@MaxBean Validation 제약 조건을 명시적으로 바인딩하고 보유 잔액 초과 여부를 추가 검증하도록 조치했습니다. 사용자가 입력단에 음수 값을 삽입하여 패킷을 우회 송신하더라도, 컨트롤러 진입 전 단계인@Valid검증 계층에서 안전하게 차단하여 HTTP 400 오류를 반환함을 실증했습니다.
── 1-4. SSRF / File Inclusion 공격 가능성 (중요 - 이행완료)
- Case 1 (템플릿 경로 조작 로컬 파일 유출 - LFI): 통합 정산서 PDF 리포트 생성 API 호출 시
template변수값을 파일 경로로 직접 수용하던 위험한 코드를 삭제했습니다.IntegratedReportRequest내에 오직verification과business단어 포맷만 수용되도록 강력한@Pattern검증 및 화이트리스트 enum 변환 구조를 정해서 경로 조작 문자 주입 시 즉각 차단됩니다. - Case 2 (로고 주소 조작 내부망 요청 위조 - SSRF): 요청 DTO 파라미터에서 클라이언트가 목적지 URL을 직접 제어할 수 있었던
logoUrl필드를 기술적으로 모두 영구 삭제 처리했습니다. PDF 헤더 로고 처리는BrandLogoLoader컴포넌트를 이용해 서버 시스템 클래스패스 내부에 번들링 보관된 안전한 정적 이미지 리소스 자원만 로드하도록 변경하여 내부망 메타데이터 접속 위협을 근본적으로 소멸시켰습니다.
── 1-5. 검증되지 않은 리다이렉트와 포워드 (일반 - 이행완료)
- 보완 조치: 임시 개발용 호스트 규칙이 운영 서버 환경에 잔재하여 동일출처정책(SOP)을 깨뜨릴 수 있었던 CORS 보안 설정을 수정했습니다.
CorsOriginProperties구조를 개편하여 공식 운영 프로필 환경(prod)에서는allow-localhost=false구동을 기본값으로 적용하고 공식 운영 도메인 패턴(https://*.onde.click)만 활성화되도록 분리 격리했습니다. - 동적 검증:
CorsOriginStartupValidator컴포넌트를 탑재하여 prod 프로필에서 localhost 허용 규칙이 활성화되면 애플리케이션 기동 자체를 즉각 중단(Shutdown)시키도록 통제를 강화했으며, curl 툴을 통한 위조 오리진 OPTIONS 요청 타격 시 차단 처리가 정상 작동함을 최종 입증했습니다.
── 1-6. 입력 값 크기 및 정확성 검증오류 (중요 - 이행완료)
- 보완 조치: 회원가입, 프로필, 게시글, 항공 예약, 결제 요청, 댓글, 매물 등록과 검색 쿼리 스트링 등 전체 파라미터의 수치 범위 및 데이터 길이 제한 누락을 고치기 위해
ValidationLimits기준을 만들고 상·하한 필터를 적용했습니다. - 동적 검증: 변조 스캐너로 DB 컬럼 허용 범위를 넘는 대용량 더미 데이터와 잘못된 형식의 필드를 넣어 전송한 결과, 500 내부 오류 대신
GlobalExceptionHandler에서 정해진 한글 검증 메시지와 함께 HTTP 400 Bad Request로 처리되는 것을 확인했습니다.
3. 취약한 파일 처리 영역 (2-1 ~ 2-2)
── 2-1. 악성코드파일 업로드 (중요 - 이행완료)
- 보완 조치: 파일 업로드 로직에서 확장자와 MIME 검증이 빠져 저장형 XSS와 RCE(원격 코드 실행)로 이어질 수 있던 문제를 고치기 위해 공통 모듈
ImageUploadValidator를 추가했습니다. JPG, PNG, WEBP 확장자 화이트리스트와 파일 헤더 매직 바이트(Magic Byte) 검사를 함께 적용해 실제 파일 형식을 확인합니다. - 동적 검증: 파일명 내 경로 조작 문자(
../등) 필터링과 함께MultipartInputValidator연동을 통해 파일당 10MB 크기 제한 및 업로드 용량 한도를 설정했습니다. Burp Suite 도구로 이미지 파일 뒤에 우회 스크립트를 은닉 주입하거나 파일명을evil.html로 위장 전송한 변조 시도 모두 "허용되지 않은 파일 확장자입니다" 검증 예외와 함께 HTTP 400번으로 처음부터 거부 차단됨을 실증 마감했습니다.
── 2-2. 중요 정보 파일 다운로드 가능성 (중요 - 이행완료)
- 보완 조치: 통합 예약 명세서 리포트 생성 과정에서 공격자가
template파일 경로 지정 인자 레이어에 Path Traversal 구문을 인젝션하여 서버 내부 기밀 파일 자산을 다운로드 PDF 출력물에 노출 및 유출시킬 수 있었던 결함을 통제 패치했습니다. 앞서 [1-4] 지표와 연계하여 클라이언트가 서버 내부의 실제 물리 디렉터리 경로를 명시적으로 파싱 주입할 수 없도록 입력 구조를 없앴습니다. - 동적 검증: 오직 사전에 시스템에 규정된 템플릿 코드 식별자 명세(
verification,business) 화이트리스트 변수만 수용하도록 엄격화하고,../기호 조합 데이터 전송 시ValidationException분기망에 걸려 중요 설정 정보 파일(.env등)이 외부로 절대 유출되지 않도록 구조적 안전 장치를 구축했습니다.
4. 취약한 접근 통제 관리 영역 (3-1 ~ 3-6)
── 3-1. 패스워드 정책 유무 및 반영 여부 (일반 - 이행완료)
- 보완 조치: 단순 수치나 영문 조합만으로 계정이 생성되어 무차별 사전 대입 공격(Brute Force)의 제물이 될 수 있었던 회원가입 계정 생성 취약점을 소멸시키기 위해 core-module 내부에
PasswordPolicy규칙 엔진 및@ValidPassword사용자 정의 Bean Validation 속성을 새로 추가 적용했습니다. - 동적 검증: 일반 가입 시 영문·숫자·특수문자 중 3종 이상 조합 시 최소 8자 이상, 2종 조합 시 최소 10자 이상의 복잡도 길이를 적용하고 약한 비밀번호 블랙리스트와 공백 문자를 서버단에서 사전 거부하도록 설계했습니다. 가입 단계에서 정책 미달 암호 주입 패킷 전송 시 정책 안내 메시지와 함께 HTTP 400으로 안전하게 거절 처리됨을 확인했습니다.
── 3-2. 인증 실패 횟수 제한 (일반 - 이행완료)
- 보완 조치: 비밀번호 검증 실패를 제한 없이 허용해 계정 탈취 위험이 있던 로그인 API를 보완하기 위해 members 테이블에
failed_login_attempts카운터와login_locked_until타임스탬프 컬럼을 추가했습니다. 백엔드에LoginAttemptService를 연결해 비밀번호 불일치가 연속 5회가 되면 계정을 30분간 임시 잠금 처리했습니다. - 동적 검증: 변조 자동화 공격 툴을 기동해 동일 이메일 주소로 오답 패킷을 연속 타격해 본 결과, 5회 실패 이후 6번째 요청부터는 올바른 정상 정답 비밀번호 데이터를 가로채 송신하더라도 세션 통제를 선검사하여 접근을 거부하고 HTTP 423 잠금 오류 코드를 엄격히 반환함을 입증 완료했습니다.
── 3-3. 계정 정보 파악 가능성 (일반 - 이행완료)
- 보완 조치: 비인증 사용자 대상의 댓글 목록 API 조회 응답 내에 작성자의 실제 데이터베이스 시퀀스 고유 식별자인
memberId키가 평문 유출되던 계정 파악 결함을 조치했습니다. 응답 규격판인CommentDto매핑 구조를 변경하여 내부 memberId 변수 항목을 모두 제거하고, 오직 가시적인 화면 노출용authorName정보와 로그인 사용자 본인 여부 판단용isMine데이터만 한정 반환하도록 데이터 명세를 최소화 정돈했습니다. - 동적 검증: 작성자 표시명은 닉네임이 없을 때 식별자가 필수 조합되지 않도록 "익명" 상수로 전역 예외 처리했으며, 프록시 도구로 응답 패킷 본문 JSON 구조를 파싱 추적한 결과 memberId 키 자체가 영구 결여되어 유출 경로가 차단되었음을 확인했습니다.
── 3-4 ~ 3-6. 관리자 도메인 격리, 검색 노출 방지 및 백업 자산 전수 진단 현황 (양호/완료)
- 3-4. 관리자 페이지 분리 여부 (이행완료): 사용자 서비스와 어드민 채널을 물리 격리한 것에 더해, 무작위 대입을 방지하고자 예측하기 쉬운 레거시 어드민 접속 서브도메인을 폐기하고 난독화 세그먼트 규칙을 부여한 새로운 전용 포탈 주소(
https://rookies.onde.click/onde-entry-8k2p) 체계로 변경을 완료했습니다. 외부 비인가자가 구 경로인/admin주소로 필수 진입 시 Nginx 프록시 및 프론트 단에서 HTTP 404 Not Found로 커넥션을 끊습니다. - 3-5. 검색엔진 정보 노출 가능성 (이행완료): 공개 상용 루트 경로에 중요 도메인 디렉터리 접근 수집 제한 정책판인
robots.txt를 정하고, 비공개 권한 포탈 및 파트너 셀러 페이지(/seller) 접근 통제 시 브라우저 헤더 단 내에<meta name="robots" content="noindex, nofollow">수집 거부 태그가 동적으로 삽입·작동되도록 연동 설정을 완비했습니다. - 3-6. 백업 파일 및 테스트 파일 존재 여부 (양호): 배포 형상 관리 도중 도출될 수 있는 소스 흔적 및 임시 백업본 파일 존재 여부를 가려내기 위해 60대 다중 추측성 페이로드 사전 파일 셋을 Burp Intruder 도구에 실어 전수 무작위 대입을 타격했습니다. 확인 결과 유효한 은닉 자산 경로는 노출되지 않았으며 전체 미존재 경로에 대해 404 또는 안전한 예외 제어 가드가 유효하게 통합 작동 중임을 입증했습니다.
5. 다음 단계: #27 하편 개발일지와 전체 이행 완료 검증
이로써 전체 28개 체크리스트 중 상편 범위에 해당하는 핵심 입출력값 검증 필터와 접근 통제 계층 보완 작업을 검증했습니다.
이어지는 [최종 프로젝트 #27] 개발 일지(하편)에서는 세션 하이재킹 위험을 줄인 4-1 쿠키 및 웹 스토리지 조작 가능성 항목부터, 5-2 요청·응답 민감 정보 마스킹, 6-1 전역 500 에러 기술 스택 메시지 마스킹, 8-1 Redis 비밀번호 인증 설정까지 남은 이행 결과를 정리하고 프로덕션 전체 영역을 다시 확인할 예정입니다. 하편 일지로 이어서 진행합니다.
- 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 착수