5.9 KiB · text History 67bd0f9

API Security & Rate Limiting

API Endpoints

Personal Access Tokens (PAT)

Scopes (lib/git_gud/accounts/personal_access_token.ex)

  • Granular scope system (e.g., issues:read, issues:write, repo:read, repo:write)
  • Stored as hashes — cannot be recovered if lost
  • Explicit scope checking in mobile API controllers

Mobile API (lib/git_gud_web/controllers/api/mobile/)

  • Auth via x-api-key or Authorization: Bearer <token> header
  • Per-action scope validation in controller actions
  • Endpoints:
    • AuthController — login, register, token refresh
    • CiController — CI/CD status, job logs
    • IssueController — issues CRUD
    • LabelController — labels CRUD
    • PackageController — package uploads/downloads
    • PullRequestController — PRs, reviews, comments
    • RepositoryController — repos, branches, commits, blobs
    • SessionController — session management
    • WikiController — wiki pages

Gitea-Compatible REST API

lib/git_gud_web/controllers/api/v1/

  • OrgController — organization management
  • RepositoryController — repository CRUD, forks, settings
  • WorkflowController — CI workflow management
  • Auth: per-endpoint handling (public read, PAT for write, runner token for CI)

Runner Protocol (CI)

lib/git_gud_web/controllers/runner_controller.ex

  • Twirp/protobuf endpoints at /api/actions/_apis/runner.v1.*
  • Methods: Ping, Register, Declare, FetchTask, FetchSingleTask, UpdateTask, UpdateLog
  • Auth: x-runner-token header or Bearer token
  • Runner registration uses one-shot token (Runners.consume_registration_token/1)
  • Per-job JWTs minted on task claim (RunnerJwt.mint/3)

Artifact/Cache APIs

  • ActionsArtifactController — /api/actions/_apis/pipelines/workflows/:run_id/artifacts/*
  • ActionsCacheController — /api/actions/_apis/artifactcache/*
  • WorkflowArtifactController — /api/actions/_apis/workflow-artifacts/*
  • Auth: RunnerJwtAuth plug — verifies per-job JWT and job is active

OCI Registry API

lib/git_gud_web/controllers/registry_controller.ex

  • Docker registry v2 protocol
  • Token-based auth at /v2/token
  • JWT tokens for push/pull operations
  • Token signing via GitGud.Packages.Token (RS256/HS256 configurable)

ActivityPub/WebFinger

lib/git_gud_web/controllers/ap_actor_controller.ex

  • HTTP signatures (RSA-SHA256) with digest verification
  • Clock skew validation: 5-minute window
  • Content negotiation for JSON-LD / ActivityPub objects
  • WebFinger at /.well-known/webfinger

lib/git_gud_web/plugs/ap_dispatcher.ex

  • Routes ActivityPub requests to inbox handlers
  • Validates signature chains for federated actors

Rate Limiting

Implemented Controls

Federation Inbox (lib/git_gud/federation/rate_limiter.ex)

  • 60 requests/minute/source host
  • Allowlisted hosts: 5x multiplier
  • ETS-based counters with 60-second sweep interval
  • Prevents inbox flooding from remote instances

MFA Attempts (lib/git_gud/accounts/two_factor_attempts.ex)

  • Tracks failed MFA verification attempts
  • Shared with login attempt tracking

Missing Rate Limiting

  • Login/Register endpoints — No rate limiting on authentication attempts
  • Password reset/Magic links — No throttling on email sending
  • PAT token verification — No brute-force protection on token endpoint
  • API endpoints — No rate limiting on mobile API, REST API, or runner endpoints
  • Webhook delivery — No rate limiting on outbound webhook retries
  • Runner protocol — No rate limiting on FetchTask calls

Security Observations

High

No rate limiting on authentication endpoints

  • Login, registration, and magic link endpoints have no rate limiting
  • Vulnerable to credential stuffing and brute-force attacks
  • Recommendation: add IP-based rate limiting (e.g., 10 requests/minute for login, 5/hour for magic links)
  • Consider CAPTCHA or proof-of-work after N failed attempts

No rate limiting on API endpoints

  • Mobile API, REST API, and runner protocol endpoints have no rate limiting
  • Can be abused for resource exhaustion or denial of service
  • Recommendation: add rate limiting via Plug (e.g., Plug.RateLimit or custom implementation)
  • Start with 100 requests/minute per authenticated user, 10/minute for unauthenticated

Medium

PAT scopes not uniformly validated

  • Scoped token validation exists in mobile API but not consistently across all REST API endpoints
  • Recommendation: create a centralized plug for PAT scope validation
  • Apply to all API pipelines (:api, :mobile_api, :browser_api)

Runner registration token not expired

  • lib/git_gud_web/controllers/runner_controller.ex:73 — Registration uses one-shot token
  • No evidence of token expiry enforcement in the controller
  • If token is never consumed, it remains valid indefinitely
  • Recommendation: add expiry to registration tokens (e.g., 30 minutes)

API key exposure in URLs

  • Verify API keys are never logged in query parameters
  • Recommendation: add logging middleware that redacts sensitive headers/parameters
  • Use Authorization header instead of query parameters for API keys

Webhook delivery no rate limiting

  • lib/git_gud/webhooks.ex — Outbound delivery has no rate limiting
  • Malicious or misconfigured webhooks can flood external endpoints
  • Recommendation: add delivery rate limiting per webhook (e.g., 10 deliveries/minute)
  • Include retry backoff with exponential delay and maximum retry count

Low

OCI registry token TTL

  • config/config.exs:103 — Token TTL is 300 seconds (5 minutes)
  • Short TTL is good for security but increases token refresh overhead
  • Ensure token refresh logic in clients handles 401 responses gracefully

ActivityPub clock skew window

  • 5-minute clock skew window for HTTP signatures may be too permissive
  • Recommendation: make clock skew configurable (e.g., max_skew_seconds: 300)
  • Default to 30 seconds for high-security deployments