Decoration URLs derive from an unvalidated arbitrary profile field #28

Closed
opened 2026-09-12 02:13:12 -04:00 by jared · 0 comments
Owner

Severity: low · Type: security · Confidence: high

Location: src/lotus/lotusDecorations.ts:44-52, /root/code/cinny/src/app/hooks/useAvatarDecoration.ts:52-56, /root/code/cinny/src/app/features/lotus/avatarDecorations.ts:191-193

Problem

the chain is: any room member (including federated) sets the MSC4133 profile field io.lotus.avatar_decoration to an arbitrary string → useAvatarDecoration returns it verbatim with no check against DECORATION_CATEGORIESdecorationUrl(slug) interpolates it into `${CDN}/${slug}.png` with no encodeURIComponent → pushed over io.lotus.decorations → EC's safeImageUrl accepts it because it only checks protocol === "https:" || "blob:", with no host allowlist → <img src> on every participant's tile. The origin cannot be changed (the CDN prefix is absolute), but ../../.. segments traverse to an arbitrary path on drive.lotusguild.org, and ?/# in the slug let a hostile member control the query string of a request every other caller's browser makes. Note safeImageUrl would also happily render any https origin, so the only thing preventing a third-party image beacon on every tile is that the host happens to build the URL itself.

Cross-reference: the host-side slug validation is LotusGuild/cinny#64. This issue is the EC side: safeImageUrl should pin to the expected decoration origin(s), not any https host.

How to trigger

set your own io.lotus.avatar_decoration profile field to ../../../../whatever?x=1, join a call with other Lotus users.

Suggested fix

validate the slug against the known catalog (or /^[a-z0-9_]+$/) in cinny before building the URL, and pin safeImageUrl to the expected decoration origin(s) in EC rather than accepting any https host.


Filed from the September 2026 audit (branch lotus).

**Severity:** low · **Type:** security · **Confidence:** high **Location:** `src/lotus/lotusDecorations.ts:44-52`, `/root/code/cinny/src/app/hooks/useAvatarDecoration.ts:52-56`, `/root/code/cinny/src/app/features/lotus/avatarDecorations.ts:191-193` ### Problem the chain is: any room member (including federated) sets the MSC4133 profile field `io.lotus.avatar_decoration` to an arbitrary string → `useAvatarDecoration` returns it verbatim with no check against `DECORATION_CATEGORIES` → `decorationUrl(slug)` interpolates it into `` `${CDN}/${slug}.png` `` with no `encodeURIComponent` → pushed over `io.lotus.decorations` → EC's `safeImageUrl` accepts it because it only checks `protocol === "https:" || "blob:"`, with no host allowlist → `<img src>` on every participant's tile. The origin cannot be changed (the CDN prefix is absolute), but `../../..` segments traverse to an arbitrary path on `drive.lotusguild.org`, and `?`/`#` in the slug let a hostile member control the query string of a request every other caller's browser makes. Note `safeImageUrl` would also happily render *any* https origin, so the only thing preventing a third-party image beacon on every tile is that the host happens to build the URL itself. **Cross-reference:** the host-side slug validation is LotusGuild/cinny#64. This issue is the EC side: `safeImageUrl` should pin to the expected decoration origin(s), not any https host. ### How to trigger set your own `io.lotus.avatar_decoration` profile field to `../../../../whatever?x=1`, join a call with other Lotus users. ### Suggested fix validate the slug against the known catalog (or `/^[a-z0-9_]+$/`) in cinny before building the URL, and pin `safeImageUrl` to the expected decoration origin(s) in EC rather than accepting any https host. --- _Filed from the September 2026 audit (branch `lotus`)._
jared added this to the EC fork audit 2026-09 · Medium & Low milestone 2026-09-12 02:13:12 -04:00
jared added the bugpriority: lowsecurityarea: decorations labels 2026-09-12 02:13:12 -04:00
jared self-assigned this 2026-09-12 02:13:12 -04:00
jared closed this issue 2026-09-13 01:22:52 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/element-call#28