Skip to content

HtmlComposer: embeds only images inside the base path - #108

Open
vrana wants to merge 1 commit into
nette:masterfrom
vrana:embed-images-inside-base-path
Open

vrana wants to merge 1 commit into
nette:masterfrom
vrana:embed-images-inside-base-path

Conversation

@vrana

@vrana vrana commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

This was an excellent gun how to shoot yourself in the foot. An innocent code like $message->setHtmlBody('<img src="assets/logo.png">' . htmlspecialchars($userText), 'assets') allowed embedding any server file in the message. A text like [[spoiler]] used in the message threw an exception.


setHtmlBody($html, $basePath) embedded any file that a reference in the HTML pointed to, including ../ paths. The [[...]] placeholder is matched anywhere in the text and HTML escaping doesn't touch it, so when the HTML contains text from users (e.g. a notification about a private message), a user writing [[../../config/local.neon]] got that file attached to the email.

Now only images inside the base path are embedded:

  • <img src>, <body background>, url(...): a reference to a file that is missing, is not an image or is outside the base path throws Nette\InvalidArgumentException.
  • [[...]]: left untouched in such a case, because it may be just text, so text from users cannot make building the email fail either.
  • Paths are normalized lexically, so symlinks inside the base path keep working. Absolute URLs are not matched, as before.

BC breaks:

  • A reference leading outside the base path (e.g. <img src="../images/x.png">) or to a non-image (e.g. a font in url(...)) throws instead of being embedded.
  • A missing file throws Nette\InvalidArgumentException instead of Nette\IOException.

🤖 Generated with Claude Code

A reference in HTML that comes from untrusted content, e.g. [[../config.neon]]
in a user's message, embedded any readable file into the email. A reference to
a file that is missing, is not an image or is outside the base path now throws
Nette\InvalidArgumentException (a missing file threw Nette\IOException before).
[[...]] may be just a text, so it is left untouched in such a case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.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