Skip to content

HTMLEncode: escape single quotes, size the result exactly - #569

Merged
michaelJustin merged 1 commit into
masterfrom
562-htmlencode-single-quote
Oct 14, 2026
Merged

michaelJustin merged 1 commit into
masterfrom
562-htmlencode-single-quote

Conversation

@michaelJustin

Copy link
Copy Markdown
Owner

Closes #562.

djGlobal.HTMLEncode escaped only <, >, & and ". Application code that used it for a single-quoted attribute value could be broken out of:

Response.ContentText := '<input value=''' + HTMLEncode(Name) + '''>';
// Name = "' autofocus onfocus='alert(1)" used to close the attribute and add an event handler

The framework's own uses (the 404 page and the development-mode 500 page) put the value in element text and were not affected.

Changes

  • ' is now escaped as &#39;. This only adds escaping, so existing output stays valid HTML.
  • The result is sized exactly in a first pass, instead of SetLength(Result, Length(AData) * 6). When nothing needs escaping, the input is returned as-is, with no new allocation.
  • A doc comment on the declaration states where the output is safe: element text and quoted attribute values (single or double). It is not safe for unquoted attributes, JavaScript, CSS or URLs.
  • SECURITY.md "Output encoding" is updated to match.
  • CHANGELOG: entry under Security.

Tests

djGlobalTests adds:

  • ' on its own;
  • the attribute break-out from the issue;
  • text with nothing to escape, including a non-ASCII character.

The consecutive-characters test now includes ', and the widest-escape test's comment now describes the exact sizing.

  • FPC (run-fpc.cmd): 215 tests, 0 errors, 0 failures; heap trace at the clean baseline (6 blocks / 744 bytes).
  • Delphi 2009 (run-delphi.cmd): OK, 215 tests.

Both were run before the rebase onto the merged #568, which touches none of these files.

🤖 Generated with Claude Code

HTMLEncode escaped only < > & and ", so application code that used it for
a single-quoted attribute value could be broken out of with a ' (XSS).
The framework's own three uses put the value in element text and were
unaffected.

- Escape ' as &#39;.
- Size the result exactly in a first pass instead of allocating six times
  the input; return the input unchanged when nothing needs escaping.
- Doc comment: safe for element text and quoted attribute values, not for
  unquoted attributes or JavaScript/CSS/URL contexts.
- Tests: single quote, the attribute break-out from the issue, text with
  nothing to escape (including a non-ASCII character).
- SECURITY.md "Output encoding" updated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@michaelJustin michaelJustin added this to the 3.5.0 milestone Oct 14, 2026
@michaelJustin
michaelJustin merged commit 1bdcaeb into master Oct 14, 2026
2 checks passed
@michaelJustin
michaelJustin deleted the 562-htmlencode-single-quote branch October 14, 2026 18:02
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.

HTMLEncode doesn't escape single quotes

1 participant