Skip to content

Settlement status audit trail trusts a client-supplied actor field with no link to the authenticated caller #952

Description

@Mac-5

Where: PATCH /admin/settlements/:id/statusupdate_settlement_status in src/handlers/settlements.rs:172-201. The request body includes an optional actor: Option<String> (settlements.rs:137), and the handler does let actor = payload.actor.as_deref().unwrap_or("admin"); (settlements.rs:187), then passes it straight through SettlementService::update_status (src/services/settlement.rs:320-357) to queries::update_settlement_status(..., actor), which persists it into the settlement's audit/history trail. The only length constraint applied is validate_max_len("actor", actor, 50) (settlements.rs:160-163) — the value itself is entirely free text supplied by the caller.

Critically, the route sits behind admin_auth (src/lib.rs:278-280), which authenticates with a single shared bearer secret (src/middleware/auth.rs:64-100) — either from SecretsStore::valid_admin_keys() or the ADMIN_API_KEY env var — with no notion of individual admin identity. There is no mechanism tying the authenticated request to a specific person/service.

Impact: any holder of the shared admin key can attribute a settlement status change (e.g. moving a disputed settlement to adjusted with a new total, or to voided) to an arbitrary actor string of their choosing — including impersonating a specific colleague, or using a generic value to hide who actually made the change. For dispute-workflow / financial audit-trail purposes, this defeats the accountability the audit log is meant to provide.

Suggested fix: derive actor server-side from the authenticated principal (once per-admin identity exists) rather than trusting a client-supplied field; at minimum, don't let the request body override it.

Metadata

Metadata

Labels

Stellar WaveIssues in the Stellar wave programbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions