/approve-prs, /merge-prs 엔드포인트에 인증이 전혀 없고, 레포 제한도 빠져있음
まだ誰も着手していません。
- 主要言語
- JavaScript
- スター
- 2
- フォーク
- 2
- PR マージ指標
- 30日以内にマージされた PR はありません
説明
배경
엔드포인트마다 인증 방식이 제각각입니다. /webhooks는 서명으로, /internal/*는 비밀 헤더로 확인합니다. 그런데 /check-weeks·/approve-prs·/merge-prs는 아무것도 확인하지 않습니다.
방어라고 할 만한 건 validateOrganization 하나뿐입니다. 요청 바디의 repo_owner가 "DaleStudy"인지만 봅니다. 그런데 이 값을 안 보내면 기본값이 "DaleStudy"라서 아무나 호출해도 통과합니다. 사실상 없는 것과 같습니다.
문제
/approve-prs·/merge-prs가 쓰는 parsePrActionPayload에는 repo_name을 leetcode-study로 묶는 체크가 없습니다. check-weeks.js에는 있습니다. CORS도 *라 브라우저에서 바로 호출할 수 있습니다.
결국 이 두 엔드포인트는 인증도 서명도 비밀값도 없이 바디의 repo_name만으로 동작합니다. 유일한 게이트인 조직 검증은 자기 신고라 있으나 마나입니다.
시도
cross-repo 쪽은 생각보다 week 필터가 어느 정도 막아줍니다. /approve-prs·/merge-prs는 week를 필수로 받고 각 PR의 Projects v2 "Week" 필드로 거릅니다. Week 필드가 없는 PR은 week: null이라 어떤 week를 넣어도 걸리지 않고 스킵됩니다(approved: 0).
그래서 leetcode-study 보드에 없는 레포는 이 두 엔드포인트로 승인하거나 병합할 수 없습니다. daleui.com의 실제 dependabot PR(DaleStudy/daleui.com#86)로 확인해봤는데 걸리지 않습니다. 임의 레포 무인증 승인은 Week 필드가 있는 레포에서만 됩니다.
물론 승인까지는 안 되더라도 App 토큰으로 PR 목록이나 프로젝트 필드를 읽는 호출은 무인증으로 그냥 나갑니다(App이 설치된 레포에 한합니다).
위험
문제는 leetcode-study 자체입니다. 여기는 Week 필드가 있으니 아무나 {"repo_name":"leetcode-study","week":"<현재 주차>"} 하나만 던지면 인증 없이 그 주차 PR을 통째로 승인하거나 auto-merge를 걸 수 있습니다. 승인과 병합은 되돌리기 힘든 동작이라 곧바로 사고로 이어집니다.
앞으로 이 보드(Week 필드)를 쓰는 레포가 늘어나면 그 레포들도 똑같이 노출됩니다.
제안
/approve-prs·/merge-prs(그리고/check-weeks)에도/internal/*처럼 요청 인증(비밀 헤더나 서명)을 붙입니다. week 필터는 믿으면 안 됩니다. 어쩌다 막힌 것이지 인증이 아닙니다.parsePrActionPayload에도check-weeks.js처럼repo_name === ALLOWED_REPO체크를 넣습니다. 허용 레포 목록으로 관리해도 됩니다.validateOrganization이 바디 자기 신고 대신 실제 인증된 컨텍스트를 보도록 고칩니다.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
/approve-prs、/merge-prs、/check-weeks のハンドラーから始め、次に parsePrActionPayload と /internal/* で使用されている認証を調査します。check-weeks.js のリポジトリ制限と PR アクションの payload パスを比較します。アクションエンドポイントがリクエスト認証を必須とし、リポジトリを制限し、ユーザーが提供したデータではなく認証済みコンテキストから組織へのアクセスを検証すれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- javascript
- 領域
- api, authentication, security
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 静か
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 48/100