Skip to content

GET /ipfs/{cid} leaks raw sqlx/DB error text in the 500 body to unauthenticated callers (sibling of #106) #226

Description

@beardthelion

An unauthenticated GET /ipfs/{cid} can be served raw sqlx/Postgres error text (schema, constraint, or connection detail) in the 500 response body when one of the handler's initial metadata queries errors. Same class as #106, different surface (that one is git-endpoint filesystem paths; this is the /ipfs surface leaking DB internals).

Mechanism

get_by_cid (crates/gitlawb-node/src/api/ipfs.rs) maps both metadata-query errors to AppError::Internal(e) carrying the raw error:

  • ipfs.rs:170 Ok(Err(e)) => return Err(AppError::Internal(e)) (list_all_repos)
  • ipfs.rs:194 Ok(Err(e)) => return Err(AppError::Internal(e)) (list_visibility_rules_for_repos)

The DB methods propagate the sqlx error with a bare .await? (no .context()), so the wrapped anyhow::Error's to_string() is the sqlx Error Display verbatim.

error.rs:160 renders it into the client body: AppError::Internal(e) => (INTERNAL_SERVER_ERROR, "internal_error", e.to_string()), serialized as {"error","message"}. Because these arms construct Internal directly (not via ?/.into()), they also bypass the From<anyhow::Error> downcast and the opaque db_unavailable -> 503 handling, so even a connection-level failure renders raw.

The route is unauthenticated: auth: Option<...>, and the two queries run before any per-repo visibility check, after only the walk-permit admission.

Reachability / trigger

Any query- or connection-level error on those two queries (schema drift, a permissions issue, a dropped/exhausted pool connection, a statement error) returns Postgres schema/connection text to an anonymous caller.

Notes

Fix

Opaque-ify AppError::Internal response bodies (log the detail, return a generic message) — this also resolves #106 — or at minimum stop passing the raw sqlx error through these two arms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate:nodegitlawb-node — the serving node and REST APIkind:securityVulnerability fix or hardeningsev:highMajor break or real security/trust risk, no easy workaroundsubsystem:apiNode REST API request/response surfacesubsystem:storageBlob/object store, Arweave, IPFS, archivessubsystem:visibilityPath-scoped visibility and content withholding

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions