Step 318. 인정받는 제보서 작성

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부 완성

  1. 3-3의 제보서를 기준 삼아, Step 317에서 확정한 취약점의 제보서 제보서_IDOR.md를 작성합니다 — 6개 섹션 전부
  2. 재현 단계를 3-4의 다섯 질문으로 검토하고, 걸린 항목을 고친 이력을 파일 끝에 적습니다
  3. 영향도 칸에 보상 등급 근거를 씁니다 — Step 314 작전 명세서의 보상 표 문장을 인용합니다
  4. 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 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.