모의해킹 준비: 범위·테스트 계정·환경 정하는 법
모의해킹 준비를 처음 하는 팀을 위한 의뢰 전 체크리스트입니다. 점검 범위, 권한별 테스트 계정, 운영·스테이징 선택, 결제·SMS 연동, WAF 예외, 백업까지 의뢰서 템플릿으로 정리했습니다.
모의해킹을 맡기기 전에 운영자가 정해야 할 것은 여섯 가지입니다. ① 점검 범위(URL·API·앱), ② 권한별 테스트 계정, ③ 운영과 스테이징 중 어느 환경에서 할지, ④ 결제·SMS 같은 외부 연동을 어떻게 처리할지, ⑤ WAF·레이트리밋 예외, ⑥ 백업과 롤백 계획입니다. 이 여섯 가지가 계약 전에 문서로 정리돼 있으면 같은 기간과 비용으로도 점검자가 로그인 이후 영역, 권한 경계, 비즈니스 로직처럼 결과 차이가 크게 나는 곳에 시간을 더 쓸 수 있습니다.
반대로 이 항목이 비어 있으면 점검 첫 2~3일이 "계정이 안 들어와요", "WAF에 막혀서 진행이 안 돼요", "이 도메인도 범위인가요?" 같은 질문으로 흘러갑니다. 점검자는 시간 단위로 일하기 때문에, 준비 부족은 그대로 결과물의 깊이로 이어집니다.
이 글은 모의해킹과 취약점 진단의 차이나 리포트 해석은 다루지 않습니다. 의뢰 직전 단계에서 운영자가 결정하고 넘겨야 할 것만, 마지막에 그대로 복사해 쓸 수 있는 의뢰서 템플릿 형태로 정리합니다. 리포트를 받은 뒤의 해석은 취약점 점검 리포트 읽는 법에서 이어서 볼 수 있습니다.
1. 점검 범위: "도메인 목록"이 아니라 "자산 목록"으로 적는다
NIST는 SP 800-115를 인용해 교전 규칙(Rules of Engagement)을 "테스트 시작 전에 수립되어, 테스트팀이 매번 추가 허가 없이 정해진 활동을 할 수 있게 하는 문서"로 정의합니다. 핵심은 허가된 대상과 허가되지 않은 대상이 문서로 분명해야 한다는 점입니다. 범위가 모호하면 점검자는 보수적으로 움직일 수밖에 없고, 그만큼 덜 보게 됩니다.
범위는 다음 단위로 나눠 적는 것이 좋습니다.
- 웹:
https://www.example.com,https://admin.example.com처럼 호스트 단위로. 와일드카드(*.example.com)는 실제로 무엇이 포함되는지 운영자도 모르는 경우가 많으니 피합니다. - API: 베이스 URL과 함께 OpenAPI(Swagger) 문서나 Postman 컬렉션을 넘깁니다. 문서가 없으면 점검자는 프론트엔드에서 호출되는 API만 보게 되고, 앱 전용·관리자 전용 엔드포인트는 놓치기 쉽습니다.
- 모바일 앱: 스토어 링크만이 아니라 점검용 APK/IPA 빌드, 앱이 호출하는 API 호스트 목록을 같이 줍니다. 루팅·탈옥 탐지나 인증서 피닝이 있다면 점검용 빌드에서 끌지 여부도 미리 정합니다.
- 제외 대상(Out of scope): 이게 더 중요합니다. 외부 SaaS(결제창, 채팅 위젯, 고객센터 솔루션), 다른 회사가 운영하는 서브도메인, 공유 인프라는 명시적으로 제외합니다. 우리 회사 소유가 아닌 시스템은 우리가 점검을 허가할 권한이 없습니다.
클라우드를 쓴다면 제공자 정책도 확인합니다. AWS는 일부 서비스에 대해 사전 승인 없이 보안 평가를 허용하지만, DoS·DDoS 시뮬레이션은 금지하고 일부 활동은 별도 승인 절차를 요구합니다. 허용 서비스 목록은 바뀔 수 있으니 계약 시점의 공식 페이지를 기준으로 확인하세요.
범위를 정할 때의 판단 기준
모든 걸 다 넣으면 기간 대비 깊이가 얕아집니다. 우선순위는 이렇게 잡는 걸 권합니다.
- 개인정보·결제 정보를 다루는 화면과 API
- 관리자 페이지와 내부 운영 도구(외부에서 접근 가능한 경우)
- 최근 6개월 안에 새로 만들었거나 크게 바뀐 기능
- 파일 업로드, 외부 URL 입력, 웹훅처럼 서버가 외부 입력을 처리하는 기능
마케팅 랜딩 페이지나 정적 블로그는 기간이 짧다면 과감히 빼도 됩니다.
2. 테스트 계정: 권한마다 최소 2개씩
모의해킹에서 결과 차이가 가장 크게 나는 영역이 권한 경계입니다. "A 사용자가 B 사용자의 주문을 볼 수 있는가", "일반 회원이 관리자 API를 호출할 수 있는가"는 계정이 여러 개 있어야 확인할 수 있습니다. 계정을 하나만 주면 이런 수평·수직 권한 상승 검사는 사실상 할 수 없습니다.
권장 구성은 다음과 같습니다.
| 역할 | 개수 | 이유 |
|---|---|---|
| 일반 회원 | 2개 | 서로의 데이터 접근(수평 권한) 확인 |
| 유료/등급 회원 | 1~2개 | 등급별 기능 우회 확인 |
| 조직(테넌트) 관리자 | 테넌트별 1개씩, 테넌트 2개 | 다른 조직 데이터 접근 확인 |
| 서비스 관리자 | 권한 단계별 1개 | 하위 관리자가 상위 기능 호출 가능한지 확인 |
| 비회원 | – | 로그인 없이 접근되는 API 확인 |
계정을 줄 때 같이 챙길 것:
- 2단계 인증: 점검 기간에만 끄거나, 점검자가 받을 수 있는 OTP 수단을 미리 등록합니다. 매번 담당자에게 인증번호를 물어보는 구조면 하루에도 수십 번 작업이 멈춥니다.
- 데이터가 채워진 계정: 주문·게시글·결제 내역이 하나도 없는 빈 계정은 확인할 수 있는 게 적습니다. 각 계정에 샘플 데이터를 몇 건씩 미리 만들어 둡니다.
- 계정 전달 방식: 비밀번호를 메일 본문에 평문으로 보내지 말고, 비밀번호 관리자 공유 기능이나 별도 채널을 씁니다.
- 점검 종료 후 폐기 일정: 계정 비활성화 날짜를 의뢰서에 미리 적어 둡니다.
3. 운영 vs 스테이징: 어디서 할지 정하는 기준
정답은 하나가 아니고, 아래 질문에 답하면 대부분 결정됩니다.
- 스테이징이 운영과 같은 코드·같은 설정인가? 브랜치가 다르거나, 운영에만 있는 WAF·CDN·인증 설정이 있다면 스테이징 결과는 운영을 대변하지 못합니다.
- 스테이징에 실제 사용자 데이터 복사본이 있는가? 있다면 스테이징도 사실상 운영 데이터 환경입니다. 마스킹되지 않은 복사본이라면 점검 전에 정리하는 게 맞습니다.
- 운영에서 장애가 나면 감당 가능한가? 트래픽이 많거나 B2B 계약상 가용성 약속이 있다면 운영 점검은 범위를 좁히고 시간대를 제한합니다.
실무에서 가장 무난한 조합은 "스테이징에서 전체 점검 + 운영에서는 읽기 위주의 설정 확인"입니다. 운영에서는 헤더·TLS·노출된 경로·인증 흐름처럼 데이터를 바꾸지 않는 항목만 보고, 데이터를 쓰거나 지우는 시나리오는 스테이징에서 합니다.
운영에서 진행한다면 다음을 꼭 정합니다.
- 점검 가능 시간대(예: 평일 10:00~18:00, 배포 금지 시간과 겹치지 않게)
- 자동화 스캐너 사용 여부와 초당 요청 수 상한
- 삭제·대량 발송·결제 같은 "되돌릴 수 없는 동작"의 금지 또는 사전 협의
- 장애 발생 시 즉시 중단 요청할 연락 채널(전화번호 포함)
4. 결제·SMS 등 외부 연동: 테스트 모드로 분리하되 우회 통로를 만들지 않는다
결제, 문자 발송, 이메일, 알림톡, 본인인증은 점검 중 실제 비용이 나가거나 실제 사람에게 메시지가 갈 수 있는 지점입니다. 그렇다고 이 기능을 범위에서 빼면 결제 금액 변조, 인증 우회처럼 중요한 로직을 놓칩니다. 방법은 스테이징에서 PG사·문자 사업자의 테스트 모드를 쓰는 것입니다.
여기서 흔히 생기는 실수가 "점검 편의를 위한 우회 코드"를 운영에 남기는 것입니다.
# ❌ 점검 편의를 위해 넣었다가 운영에 그대로 남는 코드
def verify_sms_code(request, phone, code):
# 모의해킹 기간 동안 인증번호 고정
if request.headers.get("X-Pentest") == "true" or code == "000000":
return True
return sms_store.check(phone, code)
헤더 하나나 고정 코드로 인증이 통과되는 구조는 점검이 끝난 뒤에도 남아 그 자체로 취약점이 됩니다. 요청 값으로 동작이 바뀌는 우회는 누구나 쓸 수 있다는 점이 문제입니다.
# ✅ 환경 설정으로 제공자 자체를 교체하고, 운영에서는 기동 시 차단
import os
ENV = os.environ["APP_ENV"] # "production" | "staging"
if ENV == "staging":
sms_provider = SandboxSmsProvider(
# 테스트 계정 번호로만 발송, 발송 내역은 내부 대시보드에서 확인
allowed_numbers=load_test_numbers(),
)
else:
sms_provider = RealSmsProvider(api_key=os.environ["SMS_API_KEY"])
if ENV == "production" and isinstance(sms_provider, SandboxSmsProvider):
raise RuntimeError("운영 환경에서 샌드박스 SMS 제공자를 쓸 수 없습니다")
def verify_sms_code(phone, code):
return sms_store.check(phone, code) # 검증 로직은 환경과 무관하게 동일
검증 로직 자체는 그대로 두고, 바깥 연동만 바꾸는 게 핵심입니다. 그래야 점검자가 보는 인증 로직이 운영과 같습니다. 문자 인증 쪽에서 무엇을 점검받아야 하는지는 문자 인증 보안 체크리스트를 참고하세요.
운영에서 결제를 꼭 확인해야 한다면 소액 상품 하나와 즉시 취소 절차를 미리 합의하고, 점검자가 결제할 수 있는 카드·계좌를 회사 측에서 제공합니다.
5. WAF·레이트리밋 예외: 점검자 IP만, 기간과 범위를 제한해서
WAF가 있는 상태에서 점검하면 대부분의 요청이 차단돼 애플리케이션 자체의 취약점을 보기 어렵습니다. 그래서 보통 두 단계로 나눕니다.
- WAF 적용 상태에서 일부 확인: WAF가 실제로 무엇을 막는지 보는 용도
- 점검자 IP에 한해 WAF 예외: 애플리케이션 로직을 보는 본 점검
예외를 걸 때 주의할 점은 너무 넓게 열지 않는 것입니다. Cloudflare 문서도 IP 기반 Skip 규칙은 보안 기능을 우회하므로 신중히 쓰라고 안내하며, Skip 규칙은 차단 규칙보다 앞에 있어야 동작합니다.
# ❌ 너무 넓은 예외
(ip.src in {203.0.113.0/24}) → Skip: 모든 WAF·레이트리밋 규칙
# 기간 없음, 호스트 제한 없음, 대역 전체 허용
# ✅ 좁힌 예외
(ip.src in {203.0.113.10 203.0.113.11}
and http.host eq "staging.example.com") → Skip: 관리형 규칙, 레이트리밋
# 의뢰서에 "11/10 09:00 ~ 11/21 18:00, 종료 시 담당자 OOO 삭제" 기재
체크할 것:
- 점검사의 고정 출구 IP 목록을 계약 전에 받기
- 레이트리밋, 봇 차단, 계정 잠금 정책도 같이 예외 대상인지 결정하기(로그인 시도 제한 자체를 점검받고 싶다면 그 기능은 예외에서 빼야 합니다)
- 보안관제 서비스를 쓰고 있다면 관제 업체에 점검 일정과 IP를 미리 공유하기
- 점검 종료일에 예외 규칙을 지우는 담당자와 날짜를 정해 두기
6. 백업·로그·연락 체계: 문제가 생겼을 때 되돌릴 수 있게
모의해킹은 정상적인 사용 범위를 벗어나는 입력을 일부러 넣는 작업입니다. 대부분은 문제없이 끝나지만, 게시판에 테스트 데이터가 대량으로 쌓이거나 특정 기능이 일시적으로 오작동할 수 있습니다.
- 점검 직전 백업: DB 스냅샷과 업로드 스토리지 백업을 만들고, 실제로 복원해 본 적이 있는지 확인합니다. 복원해 보지 않은 백업은 계획에 넣기 어렵습니다.
- 테스트 데이터 식별 규칙: 점검 계정 ID 접두어(예:
pentest_)를 정해 두면 종료 후 정리가 쉽습니다. 점검 후 데이터 정리는 개인정보 파기 방법의 백업·로그 처리 기준을 같이 적용하면 됩니다. - 로그 보존: 점검 기간의 애플리케이션·WAF 로그를 평소보다 길게 보관합니다. 점검 후 "우리 탐지 체계가 이 시도를 잡았는가"를 확인하는 데 쓸 수 있습니다.
- 연락 체계: 운영 측 기술 담당자와 점검 측 PM의 연락처, 긴급 중단 요청 방법, 중대 취약점을 발견했을 때 리포트를 기다리지 않고 즉시 공유할지 여부를 정합니다.
의뢰서 템플릿
아래를 복사해 채운 뒤 견적 요청 단계에서 함께 보내면, 점검사도 기간과 인력을 더 정확하게 산정할 수 있습니다.
# 모의해킹 의뢰서 (example.com)
기본정보:
서비스 설명: "B2C 커머스, 회원 약 N명, 결제·SMS 인증 사용"
점검 목적: "신규 결제 기능 출시 전 점검 / 고객사 요구 대응"
희망 기간: "2026-11-16 ~ 2026-11-27 (평일 10:00~18:00)"
범위:
웹: [https://staging.example.com, https://admin-staging.example.com]
API: { base: https://api-staging.example.com, 문서: openapi.yaml 첨부 }
모바일: { android: 점검용 APK 첨부, ios: TestFlight 초대, 피닝 해제 빌드: 예 }
운영 환경: "https://www.example.com — 비파괴 항목(헤더·TLS·노출 경로)만"
제외: [결제창(PG사 도메인), 고객센터 위젯, blog.example.com(외부 호스팅)]
우선순위: [주문·결제 API, 관리자 페이지, 파일 업로드, 웹훅]
테스트 계정:
일반회원: 2개 (샘플 주문 각 5건)
유료회원: 1개
관리자: { 운영자: 1개, 최고관리자: 1개 }
2FA: 점검 기간 해제 / OTP 시드 공유
전달 방식: 비밀번호 관리자 공유
폐기일: 2026-11-28
외부연동:
결제: 스테이징 PG 테스트 모드
SMS/알림톡: 샌드박스, 테스트 번호로만 발송
이메일: 스테이징 메일 캐처
운영 결제 필요 시: 소액 상품 1개, 즉시 취소 합의
WAF·제한:
예외 IP: 점검사 제공 고정 IP
예외 대상: 관리형 규칙, 레이트리밋 (계정 잠금은 예외 없음)
호스트 제한: staging.example.com 계열만
예외 해제: 2026-11-27 18:00, 담당자 OOO
보안관제 공유: 예
운영 규칙:
자동 스캐너: 스테이징만, 초당 요청 상한 협의
금지 동작: 운영 데이터 삭제, 대량 발송, DoS성 테스트
긴급 중단: 담당자 전화 010-0000-0000
중대 취약점: 발견 즉시 별도 채널 공유
백업:
DB 스냅샷: 점검 전날 생성, 복원 테스트 완료
테스트 데이터 접두어: pentest_
로그 보존: 점검 기간 로그 90일 보관
자주 묻는 질문
소스 코드도 같이 줘야 하나요?
필수는 아니지만 같은 기간이라면 주는 쪽이 더 많이 찾습니다. 코드를 보면 점검자가 숨은 엔드포인트, 권한 검사 누락, 위험한 함수 사용을 빠르게 짚을 수 있습니다. 코드 전체가 부담스럽다면 라우팅·권한 설정 파일과 API 문서만이라도 주는 것을 권합니다.
스테이징이 없으면 운영에서 해도 되나요?
가능하지만 범위와 방식을 좁혀야 합니다. 비파괴 항목 위주로 하고, 데이터 변경이 필요한 시나리오는 전용 테스트 계정 안에서만 하도록 합의합니다. 점검 시간대를 트래픽이 적은 때로 잡고 직전 백업과 긴급 중단 연락 체계를 반드시 마련합니다.
WAF 예외를 주면 실제 공격 상황과 달라지지 않나요?
달라집니다. 그래서 목적이 다릅니다. WAF 예외 점검은 "애플리케이션 자체에 무엇이 있는가"를 보고, WAF 적용 상태 점검은 "현재 방어가 무엇을 막는가"를 봅니다. WAF 규칙은 우회될 수 있으므로 앱 자체의 취약점을 먼저 아는 쪽이 장기적으로 유리합니다. 기간이 허락하면 두 상태를 모두 보도록 요청하세요.
정리
- 모의해킹 준비의 핵심은 범위·계정·환경·외부 연동·WAF 예외·백업 여섯 가지를 계약 전에 문서로 정하는 것입니다.
- 테스트 계정은 권한마다 최소 2개, 데이터가 채워진 상태로 줘야 권한 경계를 제대로 점검받을 수 있습니다.
- 결제·SMS는 테스트 모드로 바꾸되 요청 값으로 동작하는 우회 코드를 만들지 말고, WAF 예외는 IP·호스트·기간을 좁혀 겁니다.
- 위 템플릿을 채워 보다가 결정이 어려운 항목이 많다면, 직접 점검이 어려운 상황에서 무료 분석 신청으로 현재 구성부터 함께 살펴볼 수 있습니다.
참고 자료
함께 읽으면 좋은 글
개인정보 처리방침 작성법: 실제 데이터 흐름과 어긋나는 6곳
개인정보 처리방침 작성 시 템플릿과 실제 서비스가 어긋나는 6곳을 다룹니다. 코드와 인프라에서 분석 도구, 처리위탁, 국외이전, 로그 보관 기간, 쿠키를 찾아내 처리방침과 대조하는 방법을 정리했습니다.
GraphQL 보안 가이드: 인가·별칭·쿼리 깊이 점검
GraphQL 보안을 REST와 다르게 봐야 하는 이유와 리졸버 단위 인가 누락, 별칭·배치 쿼리를 이용한 rate limit 우회, 중첩 쿼리 부하를 Apollo Server·graphql-yoga 설정 예시와 점검 체크리스트로 정리했다.
개인정보 마스킹 체크리스트: 화면·API·로그·엑셀 12곳
개인정보 마스킹을 화면에서만 하면 API 응답·로그·Sentry·엑셀에는 원문이 남습니다. 이름·전화번호·이메일·주소 규칙과 데이터 경로 12곳 점검표를 코드 예시와 함께 정리했습니다.