Skip to content

[Security] Validate import storageKey against tenant prefix + path traversal #288

Description

@mindsers

Summary

The Admin-gated import action reads storageKey straight from the submitted form and enqueues an import that reads it via getFileBuffer. There is no check that the key is prefixed with the caller's ${congregationId}/, and the local storage driver's path.join(LOCAL_STORAGE_ROOT, key) has no traversal guard. An admin can submit ../../<path> or another tenant's key. (Requires Admin, the file must parse as a .unitae ZIP, and legitimate keys are UUIDs → Medium.)

Affected code

  • app/features/settings/routes/congregation/import-confirm.tsx (~L190-200)
  • app/shared/infra/file-storage.server.ts (~L87, 160)

Remediation

  • Validate storageKey against ^${user.congregationId}/imports/[0-9a-f-]+\.unitae$.
  • In the storage layer, resolve the final path and assert it stays within LOCAL_STORAGE_ROOT.
  • Apply the same ownership check to the import status/confirm routes (shares the export IDOR pattern).

Severity

Medium.


Source: internal security review (commit 0360e87, 2026-07-21).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    Wishlist

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions