Skip to content

sec(api/plans): validatePlanAccountProviders leaks raw account UUID + DB error into logs (gap left by #946) #965

Closed

Description

@cristim

Summary

PR #946 (which closed #944) hardened the createPlan storage-error handling by wrapping call sites #1 (CreatePurchasePlan) and #3 (SetPlanAccounts) with mapCreatePlanStorageError (ErrNotFound -> 404, otherwise a structured log + generic 500 with no raw-error leak).

It left call site #2 unwrapped: the inner GetCloudAccount DB-error path of validatePlanAccountProviders in internal/api/handler_accounts.go (~line 1167-1168) still returns:

return fmt.Errorf("accounts: failed to get account %s: %w", aid, getErr)

On a DB error there, the non-ClientError propagates up to the router's logging.Errorf("API error: %v", err), which logs the raw account UUID and the raw DB error string. This is a PII / info-leak into logs.

Issue #944(b) explicitly required structured logs carrying the account count, not IDs, and "never raw account IDs". The user-facing body is already a generic 500 (the leak is log-side only), but the log line is the gap.

Scope

validatePlanAccountProviders is shared by both createPlan (POST /plans) and setPlanAccounts (PUT /plans/:id/accounts), so the fix applies to both.

Fix

Wrap the GetCloudAccount DB-error case so it (a) emits a structured logging.Errorf with provider/service/account-COUNT (never the UUID), and (b) returns a generic 500 ClientError ("failed to validate plan accounts") carrying no raw UUID or DB string. Reuse the existing mapCreatePlanStorageError helper. Keep ErrNotFound -> 404 (account-not-found must still 404).

Regression test

Assert that a DB error in the provider-validation path yields a 500 whose error message and the emitted log contain neither the account UUID nor the raw DB error string, and that account-not-found still returns 404.

Refs #944, #946.

Activity

  1. added 6 commits that reference this issue on Jun 5, 2026
    09d4658
    36777a2
    9b1a285
    0d71341
    c126100
    b783c27
  2. added
    pr-createdA PR has been opened for this issue (dedup guard for the auto-PR loop)
    on Jun 7, 2026
  3. added 4 commits that reference this issue on Jun 8, 2026
    5052db5
    7265ab2
    3c6e0b6
    0293ace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    impact/internalTeam-internal onlypr-createdA PR has been opened for this issue (dedup guard for the auto-PR loop)pr-mergedThe PR for this issue has been mergedpriority/p2Backlog-worthyseverity/mediumModerate harmtriagedItem has been triagedtype/securitySecurity findingurgency/this-sprintWithin the current sprint

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions