Skip to content

fix: escape single quotes in HTML filter#337

Draft
Koan-Bot wants to merge 1 commit intoabw:masterfrom
atoomic:koan.atoomic/html-escape-single-quotes
Draft

fix: escape single quotes in HTML filter#337
Koan-Bot wants to merge 1 commit intoabw:masterfrom
atoomic:koan.atoomic/html-escape-single-quotes

Conversation

@Koan-Bot
Copy link
Contributor

Summary

  • Adds single-quote escaping ('') to html_filter() in Template::Filters and escape() in Template::Plugin::HTML
  • Uses ' (numeric entity) which is valid across all HTML versions, unlike ' which is only defined in XML
  • The xml_filter already handled single quotes via ' — its comment is updated to clarify the distinction
  • This prevents XSS in single-quoted HTML attribute contexts

Security context

Without this fix, template output inserted into single-quoted HTML attributes (e.g. <div title='[% var | html %]'>) could break out of the attribute and inject arbitrary HTML/JS.

Test plan

  • Updated existing test expectation in t/filter.t (double-quote test now also expects escaped single quotes)
  • New test in t/filter.t covering mixed dangerous characters
  • New test in t/html.t for HTML.escape() with single quotes in attribute context
  • Updated t/vmethods/text.t expected output for .html vmethod
  • Verified xml_filter still uses &apos; (XML named entity) — no regression
  • Full test suite: 2965 tests pass

🤖 Generated with Claude Code

Single quotes were not escaped by the HTML filter or HTML plugin's
escape method, creating XSS risk in single-quoted HTML attributes.

Uses &abw#39; (numeric entity) which is valid across all HTML versions,
unlike &apos; which is only defined in XML. The xml_filter already
handled single quotes via &apos; — its comment is updated to clarify
the distinction.

Test coverage added for both filter.t, html.t and vmethods/text.t.

Co-Authored-By: Kōan <koan-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant