Skip to content

GitHub error responses leak upstream details to clients #215

@amaydixit11

Description

@amaydixit11

Security Vulnerability

When the GitHub Search API returns an error response, the full upstream error JSON is leaked to the client, potentially exposing authentication tokens in response headers.

Affected File

api/leaderboard/views.py:180-193

Problem

if response.status_code != 200:
    error_detail = None
    try:
        error_detail = response.json()  # ← Raw upstream response
    except ValueError:
        error_detail = response.text

    return Response({
        "error": "Failed to fetch data from GitHub.",
        "upstream_status": response.status_code,
        "details": error_detail  # ← Exposed to all clients
    }, status=response.status_code)

The error_detail contains the raw response from GitHub's API. While response.json() typically doesn't include response headers, this pattern is dangerous because:

  1. GitHub error responses may contain rate limit info that aids attackers
  2. The raw response.text could leak stack traces or internal info
  3. This pattern sets a bad precedent for error handling across the codebase

Steps to Reproduce

  1. Set an invalid GitHub token or exhaust rate limits
  2. Call GET /api/github/organisation/?pr_key=test
  3. Observe the full upstream error response is returned to the client

Proposed Fix

Return sanitized error messages only:

if response.status_code != 200:
    error_detail = None
    try:
        error_detail = response.json()
    except ValueError:
        error_detail = response.text
    
    # Log the full details server-side for debugging
    logger.error(f"GitHub API error {response.status_code}: {error_detail}")
    
    # Return only safe information to the client
    client_message = {
        "error": f"Failed to fetch data from GitHub (HTTP {response.status_code}). Try again later."
    }
    if response.status_code == 401:
        client_message["error"] = "GitHub API authentication failed. Contact the administrator."
    elif response.status_code == 403:
        client_message["error"] = "GitHub API rate limit exceeded. Please try again in a minute."
    
    return Response(client_message, status=response.status_code)

Severity

MEDIUM — Information disclosure that could aid attackers in reconnaissance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    advancedComplex issues requiring experienced contributorsbugbug d73a4a 'Something isn't working'securitysecurity d73a4a 'Security vulnerability'

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions