Yaamlabs
Case study 10

Unreleased assets and a stored script

Media and advertising

An agency platform hosted campaign assets before launch and let clients comment on them. We were asked whether an asset could be read by the wrong client, and whether a comment could carry more than text.

Web & API penetration test, Creative agency platform, severity HIGH, reported 2024

At a glance

  • Challenge. A comment field stored user text and later showed it to other users as markup, so a comment could run as a script in the reader's session.
  • Approach. We used two client accounts, submitted a comment containing markup, and watched whether it rendered as markup when another account opened the thread.
  • Result. User text is now encoded on output wherever shown and asset references enforce ownership, then both surfaces were retested.
  • Impact. A script stored in a comment ran in the session of any client or staff who opened the thread, inheriting their reach to other clients' work.
  • Classification. CWE-79 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'), OWASP Top 10 (2021): A03 Injection. Component: Comment thread rendering.

The challenge

An asset reference that resolves to a file without checking who is asking treats every unreleased campaign as public to anyone who can count. Confidentiality before launch is the whole point of a staging platform, and a reference that ignores ownership removes it.

A comment field carries a second risk. If what a user types is later shown to another user as markup rather than as text, the comment stops being a message and becomes an instruction that runs in the reader's session. The author writes it once and the platform delivers it to whoever opens the thread.

On a platform where the readers are clients and staff with access to other clients' work, a script that runs in their session inherits their reach.

Our approach

We used two client accounts and asked whether an asset reference issued to one could be read from the other, then submitted a comment containing markup and watched whether it rendered as markup when another account opened the thread.

Around those two findings we checked the surface that shared the assumption:

  • Whether asset and download references enforced ownership on the resolved file
  • Whether user text was encoded on output everywhere it was shown
  • Whether previews and thumbnails shared the asset access check
  • Whether other free-text fields reached a viewer without encoding

Delivered with the references and the comment used, so each finding could be reproduced against a test workspace without taking our word for it.

From finding to fix

  1. Requested an asset from another client
  2. Read an unreleased campaign file
  3. Stored a script in a comment thread
  4. Enforced ownership and encoding, retested

The outcome

Asset references now enforce ownership on the resolved file rather than on the session, and previews inherit the same check. User text is encoded on output wherever it is displayed, so a comment is shown as a comment.

We retested the asset surface and the comment fields after the fix. Reported as HIGH in 2024. Retest included in the engagement.

Check your own system

  • Encode user text on output everywhere it is displayed, so a comment is shown as text and not markup.
  • Check every free-text field, not only comments, for a path that reaches a viewer without encoding.
  • Enforce ownership on the resolved asset and its previews and thumbnails, not on the session.
  • Confirm download references cannot be walked from one client's workspace to another's.

Read more case studies, see Web Application Penetration Testing, or write to hello@yaamlabs.com.