Skip to content

[LiveComponent] Document IDOR / write-surface sharp edges on LiveProp#3545

Open
Amoifr wants to merge 3 commits into
symfony:3.xfrom
Amoifr:feature/livecomponent-idor-docs
Open

[LiveComponent] Document IDOR / write-surface sharp edges on LiveProp#3545
Amoifr wants to merge 3 commits into
symfony:3.xfrom
Amoifr:feature/livecomponent-idor-docs

Conversation

@Amoifr

@Amoifr Amoifr commented May 15, 2026

Copy link
Copy Markdown
Contributor
Q A
Bug fix? no
New feature? no
Deprecations? no
Documentation? yes
Issues
License MIT

Doc-only resubmission of #3541 (closed alongside #3540) — rebased onto `3.x` and the Q/A header is now in place, as @Kocal asked on related PRs. No behaviour change.

`#[LiveProp]` has a few intentional, by-design sharp edges that aren't surfaced at the attribute declaration site:

  • `url: true` on an entity-typed prop — the identifier comes from the query string and is loaded with no authorization check (same trust model as `#[MapEntity]`).
  • `writable: true` on an entity-typed prop — same via the `updated` payload.
  • `writable: true` on a plain object prop — `hydrateObjectValue()` writes client-supplied property names; `PropertyAccessor` bounds this to the class's public write surface, but any public setter is reachable.

These are documented tradeoffs of the component model, not bugs — the change just makes them visible at the call site so a developer doesn't have to derive them from the hydrator internals.

Commits

  • `[LiveComponent] Document IDOR risk of url-mapped LiveProp on entity types` — note on `LiveProp::$url`
  • `[LiveComponent] Document IDOR risk of writable LiveProp on entity types` — note on `LiveProp::$writable`
  • `[LiveComponent] Note write-surface exposure when hydrating plain object props` — inline comment in `LiveComponentHydrator::hydrateObjectValue()`

cc @kbond @smnandre — wording open for discussion; happy to move some of this into the reference docs instead if you'd rather keep the docblocks terse.

Amoifr added 3 commits May 15, 2026 16:05
…ypes

When a #[LiveProp(url: true)] property is typed as a Doctrine entity (or
any object loaded via HydrationExtensionInterface), the identifier read
from the query string is trusted as-is by the hydrator. Anyone visiting
"?article=999" loads that entity into the component, with no authorization
check happening at the framework level.

This is by design — the same mechanism is exposed for writable: true and
matches Symfony's ParamConverter behaviour — but the sharp edge is easy to
miss when reading the attribute alone. Document it on the docblock so the
expectation is explicit at the call site.
A writable: true LiveProp typed as a Doctrine entity lets the frontend
swap the identifier in the "updated" payload, which the hydrator turns
into a fresh entity lookup with no authorization check.

Same intent as the previous commit on $url: documenting an existing sharp
edge so it's visible at the attribute declaration site.
…ct props

The "plain object" branch of hydrateObjectValue() takes the property names
to write straight from the client-supplied array. PropertyAccessor still
honours visibility (a setter or public property is required), so the
surface is bounded — but anyone using writable: true on a DTO with public
setters is unwittingly exposing them.

Add an inline note so the constraint is visible next to the code that
enforces it, instead of being something a reviewer has to derive from
PropertyAccessor's semantics.
@carsonbot carsonbot added Documentation Improvements or additions to documentation LiveComponent Status: Needs Review Needs to be reviewed labels May 15, 2026
@Kocal Kocal requested review from kbond and smnandre May 15, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation LiveComponent Status: Needs Review Needs to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants