4.5 KiB · text History b868907

Error Handling & Security Headers

Error Handling

Implemented Controls

Error Pages

  • lib/git_gud_web/controllers/error_html.ex — HTML error pages (404, 500, etc.)
  • lib/git_gud_web/controllers/error_json.ex — JSON error responses
  • Consistent error format across HTML and JSON endpoints
  • Generic messages that don’t leak implementation details

Authentication Errors

  • Hook/auth failures log warnings with IP address
  • Runner protocol errors return Twirp-style error codes (e.g., unauthenticated, invalid_argument)
  • Generic messages for auth failures — no stack traces or internal details

Runner Protocol Error Handling

  • runner_controller.ex — Twirp error responses with structured error codes
  • Protobuf error messages include code and message fields
  • Connect-Go client compatibility verified

Database Error Handling

  • Ecto changeset errors returned to clients
  • No raw SQL errors exposed (Ecto catches and wraps errors)
  • Constraint violation errors handled gracefully

Security Headers

Implemented Controls

Browser Pipeline (:browser pipeline)

  • put_secure_browser_headers plug
    • Sets standard security headers
    • Applied to all browser routes
    • Includes: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection

Session Cookies

  • SameSite=Lax on session cookies
  • Secure flag for HTTPS-only transmission
  • HttpOnly flag on session cookies (prevents JavaScript access)

Runner Protocol Responses

  • Connection: close header on runner protocol responses
  • Prevents HTTP/1.1 keep-alive framing attacks
  • Bandit + forgejo-runner Connect-Go compatibility

Content-Type Headers

  • All JSON responses: application/json
  • All HTML responses: text/html
  • Prevents MIME-type confusion attacks

Security Observations

Medium

No Content-Security-Policy (CSP) header

  • CSP provides defense-in-depth against XSS and data injection
  • Restricts sources for scripts, styles, images, fonts, etc.
  • Recommendation: add CSP header via Plug
    • Start with Content-Security-Policy-Report-Only for testing
    • Example: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';
    • Gradually tighten as issues are resolved

X-Frame-Options not explicitly set

  • put_secure_browser_headers may set this, but verify it’s not being stripped
  • X-Frame-Options: DENY prevents clickjacking attacks
  • Recommendation: explicitly set header via Plug
    • put_resp_header(conn, "x-frame-options", "deny")

X-Content-Type-Options not explicitly set

  • put_secure_browser_headers may set this, but verify it’s not being stripped
  • X-Content-Type-Options: nosniff prevents MIME-type sniffing
  • Recommendation: explicitly set header
    • put_resp_header(conn, "x-content-type-options", "nosniff")

No CORS configuration

  • Phoenix default applies (permissive)
  • API endpoints may be vulnerable to cross-origin attacks
  • Recommendation: add CORS headers for API endpoints
    • cors_plug library or custom Plug
    • Restrict to known origins for public APIs
    • Block all origins for private APIs

LiveDashboard accessible in development

  • Phoenix LiveDashboard at /dashboard/*
  • Exposes runtime metrics, process info, logger, IEx console
  • Critical: IEx console allows arbitrary code execution
  • Recommendation: disable dev_routes in production
    • config :git_gud, GitGudWeb.Endpoint, dev_routes: false
    • Or restrict to admin users only via plug

MailboxPreview accessible in development

  • Swoosh MailboxPreview at /dev/mailbox
  • Exposes received emails (including magic links with tokens)
  • Recommendation: disable in production
    • config :swoosh, local: false

Low

Error messages may leak implementation details

  • Some error responses include inspect(reason) which may expose internal state
  • Example: actions_artifact_controller.ex:99 — Jason.encode!(%{"error" => inspect(reason)})
  • Recommendation: use generic error messages for 4xx responses
  • Only expose detailed errors for 5xx responses in development mode

Stack traces in development

  • Phoenix may display stack traces in development
  • Could leak sensitive information (file paths, database queries, etc.)
  • Recommendation: ensure debug_errors: true is disabled in production
    • config :phoenix, :debug_errors, false

No centralized error monitoring

  • Sentry integration exists (GitGud.SentryClient) but not examined in detail
  • Verify error monitoring is configured in production
  • Recommendation: ensure Sentry DSN is configured via SENTRY_DSN environment variable
  • Add custom error handlers for critical paths