Step 318. 인정받는 제보서 작성
Level 4 — 버그바운티 | 난이도 ★★★☆☆ | 예상 소요 시간 3시간
전제: Step 317(후보 검증)을 마쳤다. 유효 취약점 1건과 증거 파일(
evidence_idor.txt)이 손에 있다.
- 준비물: 텍스트 에디터, Step 317의 검증 결과와 증거 파일. 이 챕터는 문서 작성 프로젝트입니다.
- ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다.
- 주의: 제보는 프로그램의 공식 제보 채널로만 하고, 수정·공개 전까지 내용을 외부에 공개하지 않습니다(책임 있는 공개). 랩의 계정·데이터는 전부 가공입니다.
같은 취약점도 제보서에 따라 보상이 갈립니다. 트리아저(제보 심사자)는 하루에 수십 건을 읽습니다 — 제보서는 "아무 맥락도 없는 사람이 5분 안에 재현할 수 있어야" 합니다. 오늘은 Step 317에서 확정한 IDOR을 소재로, 트리아지를 통과하는 제보서 1부를 완성합니다. 이 Level 구간의 졸업 작품입니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- 제보서의 표준 구조(요약·재현 단계·영향도·수정 제안·증거)를 설명한다
- 나쁜 제보서와 좋은 제보서의 차이를 다섯 가지 이상 짚는다
- 재현 단계를 "아무 맥락도 없는 사람" 관점에서 검토한다
- 영향도를 보상 표와 대조해 등급 근거를 쓴다
- 제보서 템플릿으로 완성본 1부를 작성한다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | 마크다운 문서 작성 (에디터 자유) |
| 오늘의 도구 | 제보서 템플릿, (개념 소개) HackerOne Hacktivity(공개 제보 열람) |
| 필요한 개념 | 재현 단계, 영향도 서술, 보상 등급 근거, 책임 있는 공개 |
| 오늘의 산출물 | 제보서_IDOR.md 완성본 1부 |
2-1. 제보서의 표준 구조
플랫폼마다 입력 칸은 조금씩 다르지만, 내용의 뼈대는 정해져 있습니다.
| 섹션 | 역할 | 분량 감각 |
|---|---|---|
| 제목 | 취약점을 한 줄로 — [기능][원인][영향] | 한 문장 |
| 요약 | 트리아저가 처음 읽는 단락 | 2~3문장 |
| 재현 단계 | 번호 목록 — 누구나 따라 할 수 있게 | 5~10단계 |
| 영향도 | 공격자가 이걸로 무엇을 할 수 있는가 | 검증/추정 분리 |
| 수정 제안 | 서버 측에서 무엇을 고쳐야 하는가 | 1~3문장 |
| 증거 | 요청/응답 원문, 스크린샷(마스킹) | 첨부 |
여섯 섹션의 순서에는 이유가 있습니다. 트리아저는 제목과 요약으로 "볼 가치가 있는가"를 판단하고, 재현 단계로 사실을 확인하고, 영향도로 등급을 정합니다. 읽는 사람의 작업 순서가 곧 문서의 섹션 순서인 것입니다.
2-2. 트리아저의 5분
트리아저의 하루는 수십 건의 제보 심사입니다. 제보서가 요구하는 것을 그들의 관점에서 보면 이렇습니다 — ① 제목만 보고 무슨 버그인지 알고 싶다. ② 재현 단계에 생략된 전제가 없어야 한다("로그인한다"가 아니라 "어떤 계정으로 무엇을 클릭한다"). ③ 영향도는 감탄사가 아니라 시나리오여야 한다. ④ 보상 등급의 근거가 프로그램의 보상 표에 연결되어 있으면 좋다.
영향도 과장은 신뢰를 깎고, 과소 서술은 보상을 깎습니다. 정답은 둘 다 아니고 사실을 정확히 쓰는 것입니다.
2-3. 책임 있는 공개
책임 있는 공개(responsible disclosure)는 취약점을 발견한 쪽이 지키는 약속입니다 — 공식 채널로만 제보하고, 기업이 수정할 시간을 주며, 수정·합의 전에는 공개하지 않는다. 대부분의 프로그램 규칙에 명시되어 있고, 어기면 보상 박탈을 넘어 법적 문제가 될 수 있습니다. 제보서를 SNS에 올리는 것은 "공개"이지 "제보"가 아닙니다.
2-4. 우수 사례 학습 — Hacktivity
HackerOne에는 채택(resolved)된 제보 중 작성자가 공개에 동의한 것들이 올라옵니다(Hacktivity). 공개 제보 3편을 읽으며 구조를 분석하는 것이 가장 빠른 학습입니다 — 제목이 어떻게 생겼는지, 재현 단계가 몇 단계인지, 영향도를 어떤 문장으로 썼는지. 실제 열람은 여러분의 몫이고, 이 챕터에서는 그 구조를 추출한 템플릿을 제공합니다.
읽을 때는 이렇게 분석해 보세요. ① 제목만 보고 취약점을 추측할 수 있는가. ② 재현 단계의 1번이 어디서 시작하는가 — 대부분 계정 생성이나 환경 설명부터입니다. ③ 영향도 문장이 "무섭다"가 아니라 "공격자가 ~를 할 수 있다"의 시나리오인가. 세 가지를 체크하며 3편을 읽으면, 좋은 제보서의 골격이 눈에 들어옵니다.
3. 따라 하기
3-1. 나쁜 제보서 해부
먼저 거절되는 제보서가 어떻게 생겼는지 봅니다. 같은 IDOR 제보입니다.
제목: 심각한 보안 문제 발견
안녕하세요. 여러분 사이트에 심각한 취약점이 있습니다.
사용자 정보가 다 보입니다. 빨리 고치세요.
제가 찾은 거니까 보상 많이 주세요.
읽는 법: 무엇이 문제인지 세어 보세요 — ① 제목에 취약점 정보가 없다. ② 어떤 기능인지 없다. ③ 재현 방법이 없다. ④ 영향이 감탄사다("다 보입니다"). ⑤ 보상 요구가 압박이다. 이 제보는 재현이 불가능하므로 N/A로 돌아갑니다.
3-2. 좋은 제보서 — 템플릿
뼈대를 먼저 확보합니다.
# 제목: [기능]에서 [원인]으로 인해 [영향]이 가능합니다
### 요약
(2~3문장 — 무엇이, 왜, 얼마나 심각한가)
### 재현 단계
1. (계정 생성부터 — 아무 전제도 생략하지 않는다)
2. ...
### 영향도
- 검증됨: (증거가 있는 사실)
- 추정: (구조로부터의 확장 — 반드시 분리 표기)
- 보상 등급 근거: (프로그램 보상 표의 어느 문장에 해당하는지)
### 수정 제안
(서버 측 조치 1~3문장)
### 첨부
- 요청/응답 원문 (세션·개인정보 마스킹)
- 스크린샷 (민감 정보 마스킹)
3-3. 실전 작성 — 랩의 IDOR을 제보서로
Step 317에서 실측한 결과로 템플릿을 채웁니다. 재현 단계는 랩 기준으로 쓰고, 실전 제보라면 실제 URL과 계정 생성 절차가 들어갑니다.
# 제목: API 사용자 조회에서 소유자 검증 부재로 타인 개인정보 열람 가능 (IDOR)
### 요약
`/api/v1/users/{id}` 엔드포인트가 로그인 여부만 확인하고 요청자와
리소스 소유자의 일치를 검증하지 않습니다. 임의 계정으로 로그인한 뒤
ID를 바꾸는 것만으로 다른 사용자의 이메일·전화번호·주소가 노출됩니다.
### 재현 단계
1. 테스트 계정 2개(A, B)를 생성합니다. (랩: alice=1001, bob=1002)
2. A로 로그인합니다:
POST /api/v1/login {"user": "alice", "pw": "alice-pass!"}
3. A의 세션으로 B의 리소스를 요청합니다:
GET /api/v1/users/1002
4. 응답 200에 B의 개인정보가 포함됩니다 (첨부 1).
### 영향도
- 검증됨: A 세션으로 B 계정(id 1002)의 이메일·전화번호·주소 1건 열람.
- 추정: ID가 연쇄 숫자 구조이므로(1003은 404 확인) 전체 계정 수만큼
노출될 것으로 보입니다. 다른 실존 계정 데이터는 열지 않았습니다.
- 등급 근거: 보상 표의 "Medium — IDOR 등 타인 데이터 열람"에 해당합니다.
### 수정 제안
서버 측에서 요청자의 세션 사용자와 조회 대상 id의 소유 관계를 검증하고,
불일치 시 403을 반환해야 합니다. 연쇄 숫자 ID를 추측 불가능한 식별자로
바꾸는 것은 보조 수단입니다(근본 해결은 권한 검증입니다).
### 첨부
- 첨부 1: 요청/응답 원문 — evidence_idor.txt (세션·개인정보 마스킹)
읽는 법: 3-1과 비교해 보세요. 재현 단계는 "계정 생성부터" 시작하고, 영향도는 검증/추정이 분리되어 있으며, 등급 근거가 보상 표의 문장에 연결됩니다. 이 제보는 트리아저가 5분 안에 재현할 수 있습니다.
3-4. 자기 검토 — 맥락 없는 독자 테스트
제출 전에 제보서를 "아무것도 모르는 사람"의 눈으로 다시 읽습니다. 체크 질문입니다.
- 재현 단계 1번이 "계정 생성"처럼 가장 처음부터 시작하는가?
- 모든 URL·ID·계정명이 구체적으로 적혀 있는가?
- "당연히"라고 넘긴 전제(로그인 상태, 권한, 환경)가 없는가?
- 영향도에서 검증된 것과 추정이 분리되어 있는가?
- 증거에 세션 쿠키·타인 개인정보가 그대로 있지 않은가?
읽는 법: 하나라도 ‘아니요’면 트리아저도 같은 곳에서 막힙니다. 막히는 제보는 재검토 요청이 오가며 판정이 늦어집니다 — 매끄러운 재현이 빠른 보상입니다.
3-5. 제출 전 최종 점검
실전 제출이라면 여기서 작전 명세서(Step 314)를 다시 꺼냅니다.
□ 이 취약점의 자산이 IN 스코프인가? (예: api.lab.local — IN)
□ 금지 행위를 어긴 테스트가 없었나? (자동화 제한, DoS 등)
□ 검증이 테스트 계정 사이에서만 이뤄졌나? (A/B — 예)
□ 타인 데이터는 1건 증명에서 멈췄나? (예 — 1002 1건)
□ 증거는 마스킹됐나? (세션·이메일·주소 — 예)
읽는 법: 이 다섯 칸이 버그바운티의 윤리 요약입니다. 기술적으로 완벽한 제보도 이 중 하나가 ‘아니요’면 제보자가 위반자가 됩니다.
4. 미션과 연습문제
미션 — 제보서 1부 완성
- 3-3의 제보서를 기준 삼아, Step 317에서 확정한 취약점의 제보서
제보서_IDOR.md를 작성합니다 — 6개 섹션 전부 - 재현 단계를 3-4의 다섯 질문으로 검토하고, 걸린 항목을 고친 이력을 파일 끝에 적습니다
- 영향도 칸에 보상 등급 근거를 씁니다 — Step 314 작전 명세서의 보상 표 문장을 인용합니다
- 3-5의 최종 점검 다섯 칸을 전부 체크하고 날짜를 적습니다
연습문제
문제 1. 제목이 "심각한 보안 문제 발견"인 제보와 "[기능]에서 [원인]으로 [영향]" 형식인 제보가 트리아지 시간에 어떤 차이를 만드는지 설명해 보세요.
문제 2. 재현 단계에서 "로그인한다" 한 줄이 왜 부족한지, 트리아저 관점에서 설명해 보세요.
문제 3. 영향도 과장과 과소 서술이 각각 어떤 손해를 만드는지 설명해 보세요.
문제 4. 책임 있는 공개의 약속 세 가지를 들고, 제보서를 SNS에 먼저 올리는 행위가 왜 문제인지 설명해 보세요.
5. 모범 답안과 완료 기준
미션 모범 답안
검토 이력의 예시:
[자기 검토 이력]
- 재현 단계가 "로그인한다"에서 시작 → 계정 생성 단계(1번)를 추가함
- 영향도에 "전체 사용자 노출"을 사실처럼 기술 → 검증/추정으로 분리함
- 증거에 세션 쿠키 원문 포함 → <세션값 마스킹>으로 교체함
검증하는 법: ① 6개 섹션이 있는가. ② 재현 단계가 계정 생성부터인가. ③ 검증/추정이 분리됐는가. ④ 보상 표 문장 인용이 있는가. ⑤ 최종 점검 5칸이 체크됐는가. 전부 ‘예’이면 완성입니다.
연습문제 해답
문제 1 해답. 트리아저는 제목으로 우선순위를 정하고 심사 순서를 잡습니다. 정보 없는 제목은 파일을 열어 본 뒤에도 무슨 버그인지 다시 파악해야 하지만, [기능][원인][영향] 형식의 제목은 심사 전에 범위와 심각도의 예상을 가능하게 합니다. 같은 취약점이라도 파악이 빠른 제보가 빨리 판정됩니다.
문제 2 해답. "로그인한다"에는 어떤 계정으로, 어떤 경로로, 어떤 권한 상태인지가 없습니다. 트리아저는 제보자의 환경을 모르므로 이 빈칸을 추측으로 채워야 하고, 추측이 틀리면 재현이 실패해 "재현 불가"로 되돌아갑니다. 재현 단계는 환경의 전제까지 문장으로 고정해야 합니다 — "테스트 계정 A로 로그인한다(계정 생성은 1번 참조)"처럼요.
문제 3 해답. 과장은 재현해 본 트리아저가 "여기까지는 안 됩니다"를 확인하는 순간 제보 전체의 신뢰를 깎고, 이후 그 제보자의 주장 전체가 할인됩니다. 과소 서술은 실제보다 낮은 등급으로 판정받아 보상이 깎입니다. 둘 다 피해는 제보자에게 돌아오므로, 검증된 사실과 추정을 분리한 정직한 서술이 최선입니다.
문제 4 해답. 책임 있는 공개의 약속은 ① 공식 채널로만 제보한다, ② 기업에 수정할 시간을 준다, ③ 수정·합의 전에는 공개하지 않는다 입니다. SNS 선공개는 셋을 모두 깨고, 무엇보다 아직 고쳐지지 않은 취약점의 정보를 실제 공격자에게 제공합니다. 발견의 영광보다 사용자 보호가 먼저라는 것이 이 약속의 이유입니다.
완료 기준 체크리스트
- [ ] 제보서 표준 구조 6섹션을 순서대로 말할 수 있다
- [ ] 나쁜 제보서의 문제를 5가지 이상 짚을 수 있다
- [ ]
제보서_IDOR.md를 6섹션 모두 채워 완성했다 - [ ] 재현 단계를 "맥락 없는 독자" 질문 5개로 검토했다
- [ ] 영향도에 검증/추정 분리와 보상 등급 근거를 썼다
- [ ] 최종 점검 5칸(스코프·규칙·테스트 계정·1건 증명·마스킹)을 통과했다
6. 흔한 실수와 해결
벽 1. 재현 단계를 쓰다가 "당연한 것"을 생략한다
증상: 내 머리에서는 되는데 트리아저에게 "재현 안 됨"이 옵니다.
원인: 작성자는 맥락을 알고 있어서 생략을 알아채지 못합니다.
해결: 3-4의 다섯 질문으로 검토하세요. 특히 재현 단계가 "계정 생성"부터 시작하는지 보세요. 하루 두고 다음 날 읽는 것도 효과적입니다 — 내일의 내가 맥락 없는 독자입니다.
벽 2. 영향도를 뭘까지 써야 할지 모르겠다
증상: "전체 사용자 위험"까지 써야 하나 망설여집니다.
원인: 검증과 추정의 경계가 흐린 것입니다.
해결: "검증: 타인 게시물 1건 열람 가능 / 추정: 전체 사용자 대상일 것(연쇄 ID 구조)"처럼 나눠 쓰세요. 트리아저는 정직한 구분을 신뢰하고, 추정 칸이 등급 상향의 근거가 됩니다.
벽 3. 수정 제안이 "보안 강화하세요"다
증상: 수정 제안 칸이 추상적입니다.
원인: 원인 분석 없이 결론만 쓴 것입니다.
해결: 원인 → 조치로 쓰세요. "소유자 검증이 없다 → 세션 사용자와 리소스 id를 대조해 불일치 시 403"처럼, 서버 측 개발자가 바로 티켓으로 옮길 수 있는 문장이 좋은 제안입니다.
벽 4. 보상 이야기를 제보서에 쓴다
증상: "보상 많이 주세요"를 제보서에 넣습니다.
원인: 보상은 제보서가 아니라 판정과 보상 표가 정합니다.
해결: 제보서에서 할 수 있는 것은 등급 근거의 제시뿐입니다 — "보상 표의 ‘Medium — 타인 데이터 열람’에 해당합니다." 금액 요구는 신뢰만 깎습니다.
벽 5. 거절당할까 봐 제출을 미룬다
증상: 제보서를 며칠씩 다듬기만 합니다.
원인: 완벽주의 — 그런데 그 사이 누군가 먼저 제보하면 중복입니다.
해결: 3-5의 다섯 칸을 통과했으면 제출하세요. 제보는 선착순의 게임이기도 합니다. 부족한 부분은 트리아저의 질문에 답하며 보완하면 됩니다 — 그 대응이 Step 319의 주제입니다.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| 제보서 6섹션 | 제목 · 요약 · 재현 단계 · 영향도 · 수정 제안 · 증거 |
| 트리아저의 5분 | 맥락 없는 심사자가 바로 재현할 수 있어야 한다 |
| 영향도 서술 | 검증/추정 분리 + 보상 표 문장과 연결 — 과장도 과소도 손해 |
| 수정 제안 | 원인 → 서버 측 조치, 개발자가 바로 옮길 수 있는 문장 |
| 책임 있는 공개 | 공식 채널 · 수정 시간 부여 · 합의 전 비공개 |
| Hacktivity | 채택된 공개 제보 모음 — 구조 학습의 최고 교재 |
오늘의 명령어·코드
| 도구 | 하는 일 |
|---|---|
| 제목 = [기능][원인][영향] | 한 문장으로 취약점 전체를 전달 |
| 재현 단계 = 계정 생성부터 번호로 | 전제 생략 금지의 실천 |
| "검증됨 / 추정" 표기 | 사실과 확장의 분리 |
| 3-5 최종 점검 5칸 | 스코프·규칙·테스트 계정·1건 증명·마스킹 |
명령어보다 중요한 감각
취약점을 찾는 실력과 보상받는 실력은 다릅니다 — 후자는 "글"입니다. 같은 발견이 제목 한 줄, 재현 단계의 전제 하나, 검증/추정 구분 하나로 등급이 갈립니다. 3-1의 제보와 3-3의 제보는 같은 버그를 말하지만 하나는 N/A이고 하나는 Medium입니다. 여러분은 이제 찾는 사람이자, 찾은 것을 인정받는 사람입니다. 남은 것은 실제 제출과 트리아저와의 대화 — 그 마지막 걸음이 다음에 옵니다.
전부 체크되면 Step 318 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.