Executive brief
TinaCMS's media handler libraries accept user-provided file paths without validating they fall within the operator's configured media directory boundary. A logged-in editor can bypass intended access controls to read, write, or delete arbitrary files in the underlying cloud storage (S3, Azure Blob Storage, DigitalOcean Spaces, or Cloudinary), including files belonging to other tenants or critical application assets. In multi-tenant deployments, this enables cross-tenant data tampering and destruction.
Technical details
The vulnerability is a broken access control flaw (CWE-639, CWE-284) in the media handler middleware. The root cause: while the handler correctly enforces mediaRoot as a listing prefix on GET operations, it omits the same validation on PUT/DELETE. Specifically, next-tinacms-s3's createMediaHandler accepts a ?key= query parameter directly from req.query and passes it to a presigned PutObjectCommand without checking it starts with mediaRoot. The DELETE handler extracts objectKey from the second URL segment (req.query.media[1]) and dispatches DeleteObjectCommand with no mediaRoot prefix validation. An attacker who is an authenticated CMS editor can mint presigned URLs for any S3 key or delete any object the IAM credential permits. The same pattern repeats in next-tinacms-dos (path.join allows ../ traversal), next-tinacms-azure (no mediaRoot config exists), and next-tinacms-cloudinary (public_id destruction unvalidated). Patch versions are available: next-tinacms-s3 >= 23.0.4, next-tinacms-dos >= 23.0.4, next-tinacms-cloudinary >= 26.0.4, next-tinacms-azure >= 14.0.4.
Affected products
- TinaCMS next-tinacms-s3 < 23.0.4
- TinaCMS next-tinacms-dos < 23.0.4
- TinaCMS next-tinacms-cloudinary < 26.0.4
- TinaCMS next-tinacms-azure < 14.0.4
Timeline
- 2026-06-22: disclosed
- 2026-08-19: advisory
- 2026-08-21: patched: Patch versions released for all four adapters