Skip to content

GitHub OAuth Security Enhancement#17

Open
ShashankFC wants to merge 1 commit into
oauth-state-vulnerablefrom
oauth-state-secure
Open

GitHub OAuth Security Enhancement#17
ShashankFC wants to merge 1 commit into
oauth-state-vulnerablefrom
oauth-state-secure

Conversation

@ShashankFC

Copy link
Copy Markdown
Contributor

Test 4

Summary by CodeRabbit

  • New Features

    • Added OAuth-based GitHub login flow integration for seamless authentication
  • Bug Fixes

    • Enhanced installation validation to prevent mismatches between authenticated users and installations
    • Improved error messaging and handling for invalid installation requests, conflicts, and pending deletions
  • Tests

    • Expanded test coverage for GitHub installation flows and error scenarios

✏️ Tip: You can customize this high-level summary in your review settings.


Replicated from ai-code-review-evaluation/sentry-coderabbit#4

…#67876)

We're adding one more step in the GitHub integration installation
pipeline, namely GitHub OAuth2 authorize. This is transparent from the
UX perspective as the data exchange happens without user interaction.

The pipeline will now fail in these cases:
- If there is a mismatch between currently authenticated GitHub user
(derived from OAuth2 authorize step) and the user who installed the
GitHub app (https://github.com/apps/sentry-io)
- If there is a mismatch between `state` parameter supplied by user and
pipeline signature
- If GitHub could not generate correct `access_token` from the `code`
(wrong or attempt of re-use of `code`).

In all those cases, this error is shown:

![image](https://github.com/getsentry/sentry/assets/1127549/18923861-2ead-4cf5-adda-7738aef801d7)
@ShashankFC ShashankFC requested a review from Copilot January 30, 2026 10:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances GitHub OAuth integration security by implementing an OAuth-based login flow to validate installation requests and prevent unauthorized installations. The changes ensure that the GitHub user initiating the installation matches the user who authenticated, preventing potential security vulnerabilities where an attacker could hijack an installation process.

Changes:

  • Added OAuth authentication step before GitHub app installation
  • Implemented validation to verify the authenticated GitHub user matches the installation sender
  • Consolidated error handling into reusable helper functions

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/sentry/integrations/github/integration.py Added OAuth login view, user validation logic, and refactored error handling
src/sentry/web/frontend/pipeline_advancer.py Simplified forward install check from list to direct comparison
tests/sentry/integrations/github/test_integration.py Added comprehensive test coverage for OAuth flow and user mismatch scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return error(
request,
self.active_organization,
error_short="Github installed on another Sentry organization.",

Copilot AI Jan 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization of 'Github' to 'GitHub' to match the official brand name.

Suggested change
error_short="Github installed on another Sentry organization.",
error_short="GitHub installed on another Sentry organization.",

Copilot uses AI. Check for mistakes.
Comment on lines +425 to +428
try:
body = safe_urlread(req).decode("utf-8")
payload = dict(parse_qsl(body))
except Exception:

Copilot AI Jan 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bare except Exception catches all exceptions without logging or providing specific error context. Consider logging the exception details before returning the generic error to aid in debugging OAuth token exchange failures.

Suggested change
try:
body = safe_urlread(req).decode("utf-8")
payload = dict(parse_qsl(body))
except Exception:
body = ""
try:
body = safe_urlread(req).decode("utf-8")
payload = dict(parse_qsl(body))
except Exception as exc:
logger.exception(
"Failed to parse GitHub OAuth token exchange response",
extra={"body": body},
)

Copilot uses AI. Check for mistakes.
Comment on lines +501 to +504
if (
pipeline.fetch_state("github_authenticated_user")
!= integration.metadata["sender"]["login"]
):

Copilot AI Jan 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metadata access integration.metadata[\"sender\"][\"login\"] could raise a KeyError if the expected structure is missing. Add validation to check for the existence of these nested keys before accessing them to prevent potential crashes and improve error handling.

Suggested change
if (
pipeline.fetch_state("github_authenticated_user")
!= integration.metadata["sender"]["login"]
):
metadata = integration.metadata or {}
sender_login: str | None = None
if isinstance(metadata, Mapping):
sender = metadata.get("sender")
if isinstance(sender, Mapping):
sender_login = sender.get("login")
if pipeline.fetch_state("github_authenticated_user") != sender_login:

Copilot uses AI. Check for mistakes.
)

auth_header = responses.calls[0].request.headers["Authorization"]
auth_header = responses.calls[2].request.headers["Authorization"]

Copilot AI Jan 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a magic number index responses.calls[2] makes the test fragile. If the number or order of API calls changes, this test will break unexpectedly. Consider using a more explicit approach, such as filtering calls by URL or adding a descriptive comment explaining why this is the third call.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants