[Regression on closed #293/#127] GithubStrategy still requests the `read:org` OAuth scope, which nothing in the codebase reads
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 74/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- github, typescript
- Lĩnh vực
- authentication, backend-api-design, security
Hướng nghiên cứu
Bắt đầu tại hàm khởi tạo GithubStrategy trong src/auth/strategies/github.strategy.ts và kiểm tra src/auth/strategies/github.strategy.spec.ts để biết các tùy chọn chiến lược được kiểm thử như thế nào. Xác nhận các scope hiện đang được yêu cầu và thêm assertion hồi quy đã mô tả. Hoàn tất khi chiến lược chỉ yêu cầu user:email và bài kiểm thử xác minh chính xác mảng scope đó.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Location
src/auth/strategies/github.strategy.ts:22 — GithubStrategy constructor
scope: ['user:email', 'read:org'],
Problem
The OAuth consent request still asks GitHub for read:org in addition to user:email. Nothing in the application consumes organization data from GitHub:
GithubStrategy.validate(lines 26-42) reads onlyprofile.id,profile.username,profile.emails[0],profile.photos[0].GithubSyncServicecalls exactly two Octokit endpoints —octokit.repos.get(line 130) andoctokit.issues.listForRepo(line 217) — plus an unusedoctokit.pulls.get. Neither needsread:org, and both run under the platform's ownGITHUB_API_TOKEN(octokit.provider.ts:50), not the user's OAuth token.grep -rn 'read:org\|\.orgs\.' src/finds the scope declaration and nothing else. The only otherorgshits areReputationService'sorgsContributedTo, which is derived from local bounty/repository rows, not from GitHub's organization API.
The user's accessToken is stored on GithubAccount (encrypted at rest) but is never used to make an API call anywhere in the codebase.
This is closed issue #127, re-filed and closed again as #293. The scope is still present.
Why it matters
read:org is not a trivial scope. It grants read access to the user's organization memberships (including private memberships that the user has deliberately hidden from their public profile), the organization's teams and team memberships, and its projects. For a contributor who belongs to a private organization at their employer, consenting to MergeFi discloses that membership and that org's team structure to this platform.
Two concrete consequences:
- Consent-screen friction and trust. GitHub's authorization page lists the requested permissions verbatim. A bounty platform asking to "Read org and team membership, read org projects" for no stated reason is a reasonable cause for a contributor — or an organization admin reviewing third-party app access — to decline. Organizations can and do block OAuth apps that request org scopes.
- Unnecessary blast radius. The token is persisted in
github_accounts.accessToken. Should that column ever be read out (a misconfiguredENCRYPTION_KEY, a backup leak, a SQL-injection path), the stolen token carries org-read capability it never needed. Least privilege here is free: no feature depends on it.
Reproduction / failure path
- Configure real OAuth credentials and visit
GET /api/auth/githubas a user who is a private member of at least one GitHub organization. - Observe GitHub's consent screen: alongside "Email addresses (read-only)" it lists organization and team membership read access.
- Grant access, then inspect the granted scopes for the app under GitHub -> Settings -> Applications -> Authorized OAuth Apps.
read:orgis held. - Grep the codebase for any consumer of that capability — there is none. The scope is granted and never exercised.
Suggested fix
Drop the scope:
scope: ['user:email'],
user:email alone is sufficient for everything validate reads: profile.id, profile.username, profile.displayName, profile.profileUrl and profile.photos all come from the public user resource, and user:email is only needed for the private email address.
Add a regression test to src/auth/strategies/github.strategy.spec.ts that asserts the exact scope array passed to the Passport strategy, so a future change has to state its intent:
it('requests only the user:email scope', () => {
// assert on the options object handed to super()
expect(strategyOptions.scope).toEqual(['user:email']);
});
That test is what both previous fixes were missing — the scope has now been removed and reintroduced twice without anything failing.
If organization data is wanted later (for example, to verify a sponsor's org affiliation), add the scope back in the same change that adds the code reading it, and document in the README what it is used for so the consent screen can be explained to users.
- Ngôn ngữ chính
- TypeScript
- Star
- 2
- Fork
- 90
- Merge trung bình
- 31 phút
- Pull request đã merge (30 ngày)
- 20
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Không có hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của MergeFi/backend
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug testing
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug security
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 79/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của MergeFi/backend
Issue tương tự
-
ログイン中の404画面にヘッダーとナビを出すĐang mởCodex使用可 コード
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
ryuki-moro/Nicomaru#218 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
sveltejs/svelte-eslint-parser#1008 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
silverbucket/inbox-rs#351 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: The H2 series' and the H3C's fan 3 is labelled "Chamber Fan", Bambu calls it the exhaust fanĐang mởarea:ui
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug front P2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
invoicerr-app/invoicerr#964 ·
Maintainer thường phản hồi trong vòng 1 ngày