Skip to content

Confine CID image embedding to the base path - #15

Merged
do-io merged 1 commit into
mainfrom
fix/cid-embedder-base-path
Oct 20, 2026
Merged

do-io merged 1 commit into
mainfrom
fix/cid-embedder-base-path

Conversation

@do-io

@do-io do-io commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Hardens CidImageEmbedder::embed() when a $basePath is passed (MailBuilder::embedCidImages($html, $basePath)).

Before: a relative src was joined to the base path and read if it existed, so ../ segments or symlinks could attach files from outside the base directory, whatever their type.

Now a local file is embedded only if it:

  • resolves (symlinks and .. included) inside the base path,
  • is a regular, readable file of at most 5 MB,
  • has an image/* MIME type.

URLs, stream wrappers (php://, file://), protocol-relative addresses and NUL bytes are never treated as local paths. Calls without a base path behave as before (data URIs only).

Tests: inside-base embed, parent and deep traversal, stream wrapper, file scheme, protocol-relative, a symlink leaving the base, and a non-image file. The new tests fail on the old code. Pint, PHPStan and the full suite (152 tests) pass locally.

Not merged or tagged; waiting for the go-ahead.

When a base path is given, a relative src was joined to it and read without any check, so ../ segments or an absolute-looking path could attach files from outside the base directory. The file must now resolve (symlinks and .. included) inside the base path, be a regular readable file under 5 MB, and have an image MIME type. URLs, stream wrappers and protocol-relative addresses are never treated as local paths.
@do-io
do-io merged commit 9855618 into main Oct 20, 2026
14 checks passed
@do-io
do-io deleted the fix/cid-embedder-base-path branch October 20, 2026 15:39
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