Skip to content

fix(Helpers): escape attributes and unsupported messages in HTML media tags - #10765

Open
gr8man wants to merge 2 commits into
codeigniter4:developfrom
gr8man:fix/html-helper-media-escaping
Open

gr8man wants to merge 2 commits into
codeigniter4:developfrom
gr8man:fix/html-helper-media-escaping

Conversation

@gr8man

@gr8man gr8man commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Description

The video(), audio(), _media(), source(), track(), object(), param() and embed() helpers concatenated their arguments directly into double-quoted HTML attributes, and emitted $unsupportedMessage as raw markup. Any value containing a double quote closes the attribute it was placed in, so caller-controlled data - a src, type, kind, label, srclang, name or value coming from a database column or a request parameter - can inject arbitrary attributes such as onerror into the generated tag. In the same way, markup passed as the fallback message is rendered as HTML instead of text.

Both are escaped now:

  • attribute values go through a new _esc_attr() helper that applies htmlspecialchars() with ENT_QUOTES | ENT_SUBSTITUTE, so both quote styles, <, > and & are encoded while ordinary URLs stay readable, and invalid UTF-8 is substituted instead of emptying the value;
  • the fallback messages of video(), audio() and _media() go through esc($message, 'html').

Values are escaped exactly once - the array branch of video()/audio() reaches source(), which escapes its own arguments before _media() concatenates them. The $attributes parameters are intentionally left as-is: they are documented as raw HTML snippets supplied by the caller. Output for input without special characters is unchanged, which the existing tests assert.

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication)
  • Unit testing, with >80% coverage
  • User guide updated (the helper docs do not document the escaping behaviour; output without special characters is unchanged)
  • Conforms to style guide

…a tags

The `video()`, `audio()`, `_media()`, `source()`, `track()`, `object()`,
`param()` and `embed()` helpers concatenated their arguments straight into
double-quoted HTML attributes. A value containing a double quote - a `src`,
`type`, `kind`, `label` or `name` that comes from a database column or a
request parameter, for instance - could therefore close the attribute and
inject arbitrary ones, such as `onerror`, into the generated markup.

Attribute values now go through a new `_esc_attr()` helper that applies
`htmlspecialchars()` with `ENT_QUOTES | ENT_SUBSTITUTE`, so both quote
styles, `<`, `>` and `&` are encoded while ordinary URLs stay readable.
`ENT_SUBSTITUTE` keeps invalid UTF-8 from turning the whole value into an
empty string.

The `$unsupportedMessage` fallback text of `video()`, `audio()` and
`_media()` was emitted verbatim as well, so markup passed as the fallback
message was rendered as HTML. It is now escaped with
`esc($message, 'html')` and displayed as plain text.

Regression tests cover each affected helper, including the alternative
`ENT_SUBSTITUTE` behaviour.
@carson-codeigniter4 carson-codeigniter4 Bot added the bug Verified issues on the current code behavior or pull requests that will fix them label Nov 11, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Verified issues on the current code behavior or pull requests that will fix them

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant