Symfony 5.4.52 / 6.4.40 / 7.4.12 / 8.0.12 — seven CVEs in a single maintenance window, from SMTP header injection in Mime\Address to the UrlGenerator route-requirement bypass with off-site redirect
20 May 2026. The Symfony team has released patch versions for all four supported lines (5.4.52, 6.4.40, 7.4.12, 8.0.12) — seven CVEs in a single maintenance window. The bulk sits in the HtmlSanitizer trio (BiDi override smuggling, host allowlist bypass via URL parser differential, forgotten URL attributes) plus a UrlGenerator route-requirement bypass and a CRLF header injection in Mime\Address that exceptionally also hits TYPO3 setups directly. Anyone running Sylius, Symfony apps, or TYPO3 v12.4 LTS / v13.4 LTS / v14.x has two operational paths: a patch-pipeline-managed stack (Renovate, Dependabot or similar) where the component updates flow in automatically — or a manual update path where, today, at minimum symfony/mime (TYPO3 mailer path) and the HtmlSanitizer trio (Sylius / Symfony UGC pipelines) have to be pushed through.

TL;DR — the 90-second summary
- What was released?
Symfony 5.4.52, 6.4.40, 7.4.12 and 8.0.12 with seven CVEs: HtmlSanitizer trio (CVE-2026-45064 BiDi override in URLs, CVE-2026-45066 allowLinkHosts/allowMediaHosts bypass via URL parser differential, CVE-2026-45753 forgotten URL attributes action/formaction/poster/cite), CVE-2026-45065 UrlGenerator route-requirement bypass via unanchored regex alternation, X509Authenticator identity spoofing via unanchored DN regex, CRLF injection in
Symfony\Component\Mime\Address(email header / SMTP command injection), CVE-2024-50340 patch bypass in SymfonyRuntime.- How severe on average?
Three of the seven CVEs are directly exploitable and need to be handled with priority high: the HtmlSanitizer trio in any app that renders UGC or Markdown, the UrlGenerator bypass in any app with regex alternations in route requirements, the
Mime\AddressCRLF injection in any app that builds mail header display names from user input (newsletter, form mailer, customer confirmation).- Stack mapping — who is really affected?
Symfony-direct and Sylius: all seven CVEs potentially relevant. TYPO3 v12.4 LTS / v13.4 LTS / v14.x: exclusively the
Mime\AddressCRLF gap — since TYPO3 v10 (Feature-88643) the mail API has shifted ontosymfony/mailerandsymfony/mime,FluidEmailandMailMessagerequireSymfony\Component\Mime\Addressfor every address. The other six CVEs do not touch TYPO3, because TYPO3 uses its own routing, its own HTML cleaner, its own bootstrap, and no X509 authentication.- Am I affected with an auto-update pipeline (Renovate, Dependabot, Mend)?
If the Composer lock pins
symfony/*at any of the pre-patch versions, then yes — in a patch-pipeline-managed environment the pipeline bundles the patch versions (5.4.52, 6.4.40, 7.4.12, 8.0.12) together with the component updates (symfony/html-sanitizer,symfony/routing,symfony/security-http,symfony/mime,symfony/runtime) into merge requests against the image definitions. The container rebuild is graceful; the Symfony cache clear is part of the rebuild step.- Am I self-hosted without an auto-update pipeline?
Then yes, and you should update today. Order by risk: first the HtmlSanitizer trio apps (if UGC is in play), then UrlGenerator apps with regex route requirements (locale routes practically always), then mail pipelines with user input in display names (also applies to TYPO3 EXT:form email finishers and the Sylius Customer Mailer). Then the application redeploy with cache clear.
- Which two structural themes appear in parallel?
First, differential parser mismatch: when two code paths parse the same input differently (HtmlSanitizer URL parser vs. browser WHATWG parser, Symfony DN regex vs. OpenSSL DN parser,
parse_strvs. SAPI argv layer), bypasses open up. Second, unanchored regex alternations:'#^a|b|c$#'only binds^/$to the first and last branch because of PCRE operator precedence — everything in between becomes a substring match. The pattern hits UrlGenerator and X509Authenticator at the same time.
Operational response to the cluster
Moselwal positions itself explicitly on auto-update-ready platforms — the CTA at the bottom of this post sums that up in a sentence. The operational principle: a patch pipeline (Renovate, Dependabot, Mend) scans Composer packages several times a day and pushes new patch versions automatically into merge requests against the image definitions. A wave like the 20 May cluster therefore flows into the build pipeline without a night shift: the four Symfony patch lines (5.4.52, 6.4.40, 7.4.12, 8.0.12) including the component updates (symfony/html-sanitizer, symfony/routing, symfony/security-http, symfony/mime, symfony/runtime) show up as merge requests, the CI rebuilds the container images, the worker restarts are graceful, and the Symfony cache clear is part of the rebuild step.
Anyone not running on an auto-update pipeline — a Symfony, Sylius or TYPO3 installation that is maintained manually — has a very tight operational window on the three directly exploitable gaps. The following sections go through each advisory, what happens technically, what the exploitation prerequisites are, and what update order the maintenance work demands. Two places deserve particular attention: the UrlGenerator regex precedence (because the same class pattern reappears in the X509Authenticator) and the Mime\Address CRLF injection (because, alone among the wave’s CVEs, it also hits TYPO3 setups directly — via the Symfony Mailer path that has carried the TYPO3 mail API since v10).
One upfront content line: four of the seven CVEs structurally reduce to two classes. First, differential parser mismatches — the sanitizer parses URLs differently than the browser, the Symfony DN regex differently than OpenSSL, parse_str differently than the SAPI argv layer. Second, unanchored regex alternations — ^a|b|c$ matches in the middle as an unanchored substring, a class fault that hits UrlGenerator and X509Authenticator simultaneously. Anyone who understands the classes spots the gaps in their own code as well.
CVE-2026-45065 — UrlGenerator route-requirement bypass via unanchored regex alternation
| Field | Value |
|---|---|
| CVE | CVE-2026-45065 |
| CWE | CWE-185 — Incorrect Regular Expression / CWE-601 — URL Redirection to Untrusted Site |
| Component | symfony/routing, UrlGenerator::doGenerate() |
| Vulnerability type | Route-requirement bypass → off-site redirect via protocol-relative URL |
| Affected versions | < 5.4.52, >= 6, < 6.4.40, >= 7, < 7.4.12, >= 8, < 8.0.12 |
| Fixed versions | 5.4.52, 6.4.40, 7.4.12, 8.0.12 |
| Severity | High — direct open-redirect vector in any app with alternation requirements |
Technical analysis — PCRE operator precedence and the unanchored middle branch
The UrlGenerator validates dynamic route parameters against the route's requirements string. Before the patch, compilation looked like this:
// In Symfony\Component\Routing\Generator\UrlGenerator::doGenerate(), pre-patch:
$compiledPattern = '#^' . $requirement . '$#';
For a standard localisation route with _locale: 'de|en|fr', that becomes:
#^de|en|fr$#
Because of PCRE operator precedence, the regex engine parses that as:
(^de) | (en) | (fr$)
^ binds only to the left branch, $ only to the right — the middle alternatives are unanchored. A value like evil.com/path matches the en branch as a substring, the requirement is considered satisfied, and the UrlGenerator emits the full user value as a path segment.
If an app writes UrlGenerator output directly into a Location header or an <a href>, the result is a protocol-relative URL — the browser follows //evil.com/path and navigates to the attacker domain. A classic off-site redirect primitive in a component that was supposed to prevent exactly that.
The fix wraps the entire requirement in a non-capturing group:
// Symfony 5.4.52 / 6.4.40 / 7.4.12 / 8.0.12, post-patch:
$compiledPattern = '#^(?:' . $requirement . ')$#';
That way the anchors apply at the start and end of the whole alternation, not just at the rim branches. A one-liner functionally — structurally the correction of a class of validations that has been written this way since the Symfony 2.x era.
Stack mapping
| Stack | Affected? |
|---|---|
| Symfony-direct | ✓ when requirements contains alternations (locale routes by default) |
| Sylius 1.13.x / 2.x | ✓ — {_locale} routes and channel constraints |
| TYPO3 v12.4 LTS / v13.4 LTS / v14.x | ✗ — TYPO3 uses its own routing layer (PageRouter, EnhancersAndAspects), no Symfony\Component\Routing generator calls in the frontend |
In the Moselwal audit, 11 of 14 Sylius platforms have {_locale} requirements with de|en|fr alternation, plus four Symfony-direct apps with multi-locale or API Platform filter constraints. TYPO3 stacks unaffected. Renovate MRs arrived overnight, image rebuilds in the normal rolling window, prioritised by public-facing exposure.
HtmlSanitizer trio — CVE-2026-45064, -45066 and -45753
Three tightly related HtmlSanitizer CVEs in the same wave. Structurally all a failure of the validation layer against the downstream browser render — either through differing URL parser semantics (CVE-2026-45066), through missing BiDi override detection (CVE-2026-45064), or through an incomplete list of URL-bearing attributes (CVE-2026-45753). All three patched in Symfony 5.4.52 / 6.4.40 / 7.4.12 / 8.0.12.
CVE-2026-45066 — allowLinkHosts / allowMediaHosts bypass via URL parser differential
CWE-436 (Interpretation Conflict) plus CWE-79 (XSS). Component: symfony/html-sanitizer, host allowlist comparison. Severity: High.
The HtmlSanitizer allows a host allowlist via ->allowLinkHosts(['trusted.example']) or ->allowMediaHosts(['cdn.example']). For an <a href="..."> or <img src="..."> element the sanitizer parses the URL and checks the host against the allowlist. The bug: the sanitizer's own URL parser works on an RFC-3986-leaning representation, the browser URL parser on the WHATWG URL Standard specification. The two diverge in several places, most prominently in how they handle backslashes in the authority component:
<a href="https://trusted.example\@attacker.example/path">click</a>- Symfony pre-patch (RFC 3986 strict): backslash is a reserved character, the parser does not segment further,
host = trusted.example. Allowlist check passes. - Browser (WHATWG): in the special-scheme path the backslash is treated as a forward slash, the
@marks the userinfo/host separator — the effective host isattacker.example. The browser navigates there.
Additionally there was an <area> element misclassification: the <area href="..."> tag was categorised in the sanitizer as a media element (analogous to <img>) but belongs to the link elements according to the HTML5 spec. Consequence: the media allowlist applies instead of the link allowlist.
CVE-2026-45064 — BiDi override smuggling in URL attributes
CWE-1007 (Insufficient Visual Distinction of Homoglyphs). Severity: Medium (user interaction required, but a very smooth phishing gap in any UGC flow).
BiDi override characters (Unicode U+202E RIGHT-TO-LEFT OVERRIDE, U+2066–U+2069 isolate markers) change the visual display order of text in the browser. A URL such as example.com& is rendered visually as example.com/htap/egil.com — the user sees a trustworthy domain, the browser navigation lands somewhere else. The HtmlSanitizer let these characters through URL attributes unhandled before the patch. The fix introduces an explicit reject step: BiDi override characters are stripped before URL validation, spaces are percent-encoded.
CVE-2026-45753 — missed URL attributes action, formaction, poster, cite
CWE-79 (XSS) plus CWE-693 (Protection Mechanism Failure). Severity: Medium to high (in <form action="javascript:..."> constellations directly XSS).
The HtmlSanitizer maintains an internal list of URL-bearing attributes to which it applies the scheme allowlist and host allowlist. The list pre-patch covered the classics (href, src, srcset, formaction partly), but missed four important attributes from the HTML5 standard: action on <form>, formaction on <button> and <input type="submit">, poster on <video>, cite on <blockquote>, <q>, <del>, <ins>. A <form action="javascript:alert(1)"> therefore passes through the sanitizer unfiltered — on form submission the JavaScript URI runs in the browser context.
Stack mapping
Symfony-direct and Sylius are affected as soon as the HtmlSanitizer plus UGC are in play (forum posts, customer reviews, Markdown newsletters). TYPO3 is not affected — TYPO3 uses the standalone typo3/html-sanitizer package (namespace TYPO3\HtmlSanitizer\), which only integrates masterminds/html5 as a DOM parser. The sanitization logic itself is TYPO3's own code, not a Symfony component. In the Moselwal estate: two Sylius platforms with allowLinkHosts in the newsletter editor, three Symfony-direct apps with HtmlSanitizer UGC pipeline without host allowlist. Update with high priority in UGC flows.
CRLF injection in Symfony\Component\Mime\Address — the only CVE in the wave that also hits TYPO3
| Field | Value |
|---|---|
| CVE | CVE assignment not yet published on CVE.org; the Symfony advisory lists the gap under “Email Header / SMTP Command Injection via CRLF in Symfony\\Component\\Mime\\Address” |
| CWE | CWE-93 — Improper Neutralization of CRLF Sequences |
| Component | symfony/mime, Address constructor and toString() |
| Severity | High — directly exploitable in newsletter, form-mailer and customer-confirmation pipelines |
Technical analysis — how the display name hijacks an entire email
The class Symfony\Component\Mime\Address has the constructor signature:
namespace Symfony\Component\Mime;
final class Address
{
public function __construct(string $address, string $name = '')
{
// ...
}
public function toString(): string
{
// pre-patch: raw display name written into the header
return ($this->getEncodedName() ?: '') . ' <' . $this->address . '>';
}
}
The second parameter $name is the display name that appears in the From:, Reply-To: or To: header in the form "Display Name" <adresse@example.com>. Pre-patch the constructor did not filter the display name for CRLF sequences. An address constructed with a display name like:
new Address('user@example.com', "Foo\r\nBcc: attacker@example.com");
renders, when the header is built, as:
From: "Foo
Bcc: attacker@example.com" <user@example.com>
The CRLF in the display name breaks out of the From header quoting and injects an additional Bcc directive. The SMTP sender reads the new line as a header of its own. Result: outgoing mail with an additional invisible recipient — and/or with arbitrary further headers (Reply-To, Content-Type, even SMTP command splitting if the MTA doesn't catch it). The fix introduces strict CRLF rejection in the Address constructor. Callers that build raw from user input now get an InvalidArgumentException and see the gap in failed code directly — that's intentional, the patch is also an audit trigger.
Prerequisite — and the three standard call chains
An app that builds mail headers (especially From, Reply-To, Sender) from user input. Three call chains regularly appear in Moselwal stacks:
1. Sylius Customer Mailer. Sylius sends mails through \Sylius\Bundle\CoreBundle\Mailer\ (welcome mail, password reset, order confirmation). The from display name is typically pulled from channel settings or customer properties — and customers can set their own firstName/lastName via the self-service API. In a newsletter implementation where the customer appears as an “on behalf of” sender (B2B platform with white-label addressing), the customer name flows directly into the From header.
2. TYPO3 EXT:form email finisher. The TYPO3 form framework has an email finisher (\TYPO3\CMS\Form\Domain\Finishers\EmailFinisher) that pulls senderName and senderAddress from the form configuration. The configuration supports placeholder templates of the form {form-field-name} — direct adoption of form fields (typically “name” and “email”) into the From header. Since the finisher has run through Symfony Mailer and thus through Symfony\Component\Mime\Address since TYPO3 v10 (Feature-88643, “New Mail API based on symfony/mailer and symfony/mime”), every TYPO3 form installation with a user-configurable sender name was exposed.
3. Custom mailers in in-house code. Any TYPO3 extension or Symfony bundle that instantiates new Address($email, $displayName) with a user-influenced $displayName. Common in order-confirmation mailers, customer-support forwarders, form-to-mail plugins, notification subscriber services.
Real-world leverage: spam dispatch via the own server, phishing mails with the own domain footer, BCC exfiltration of internal mails to attacker mailboxes. Plus an indirect reputation effect — the own mail server lands on blocklists because it has been sending BCC mail to unclear destinations.
Stack mapping
| Stack | Affected? | Concrete path |
|---|---|---|
| Symfony-direct | ✓ | every new Address(...) site with user-input $name |
| Sylius 1.13.x / 2.x | ✓ | Customer Mailer, newsletter bridge, B2B sender-spoofing setups |
| TYPO3 v12.4 LTS / v13.4 LTS / v14.x | ✓ | \TYPO3\CMS\Form\Domain\Finishers\EmailFinisher, any FluidEmail/MailMessage instance with user-influenced From-name |
TYPO3 version → Symfony Mime fix line
Since TYPO3 pins the Symfony major line via its Composer constraint, the concrete fix version depends on the TYPO3 line:
| TYPO3 line | Symfony Mime constraint | Fix version |
|---|---|---|
| v12.4 LTS | ^6.4 | symfony/mime 6.4.40 |
| v13.4 LTS | ^7.0–^7.4 | symfony/mime 7.4.12 |
| v14.x (current) | ^7.0–^8.0 | symfony/mime 7.4.12 or 8.0.12 |
In every case the flow is identical: composer update symfony/mime --with-all-dependencies plus vendor/bin/typo3 cache:flush.
Distribution across the Moselwal estate
Three Sylius platforms with newsletter pipelines in which customer display names can flow into From headers — all three are patched in the prioritised wave. Two Symfony-direct apps with customer-support mailers and dynamic Reply-To. Nine TYPO3 platforms with EXT:form in production use (spread across v12.4 LTS, v13.4 LTS and v14.x), four of those with user-configurable senderName in the form definition — all four were rolled out overnight with priority.
CVE-2024-50340 patch bypass — APP_ENV / APP_DEBUG via parse_str / SAPI argv mismatch
| Field | Value |
|---|---|
| CVE | CVE-2024-50340 (patch bypass, new fix disclosed at the same time) |
| CWE | CWE-178 / CWE-863 |
| Component | symfony/runtime, argv / query-string handling in SymfonyRuntime |
| Vulnerability type | environment variable smuggling → debug mode enable in production |
| Severity | Medium to high (setup-dependent — in production with ?APP_DEBUG=1 active, information disclosure is directly possible) |
Technical analysis
CVE-2024-50340 closed a path in November 2024 through which web requests could set APP_ENV/APP_DEBUG via query string — through SymfonyRuntime, which mixed SAPI argv values with server variables. Today's patch closes a remaining bypass path: a mismatch between PHP's parse_str() output and the SAPI argv representation allowed the variables to leak through in certain embedded-worker setups (FrankenPHP, RoadRunner, Swoole). The fix strictly gates the argv path on the presence of $_SERVER['QUERY_STRING'] and compares the parsed values more rigorously.
Stack mapping
| Stack | Affected? |
|---|---|
| Symfony-direct with FrankenPHP worker | ✓ |
| Sylius with FrankenPHP worker | ✓ |
| TYPO3 v12.4 LTS / v13.4 LTS / v14.x | ✗ — TYPO3 uses its own bootstrap (\TYPO3\CMS\Core\Core\Bootstrap), no symfony/runtime |
In the Moselwal estate: all Sylius and Symfony-direct platforms run on FrankenPHP, so the bypass path is potentially relevant. The internal audit pass is running; so far no production setups show a ?APP_DEBUG=1 test trace in the logs. Update runs at priority Medium on all Sylius/Symfony stacks. TYPO3 is unaffected.
X509Authenticator identity spoofing via unanchored DN regex (same class as CVE-2026-45065)
| Field | Value |
|---|---|
| CVE | assignment not yet published; the advisory lists the gap under “Identity Spoofing via Unanchored DN Regex in X509Authenticator” |
| CWE | CWE-185 — Incorrect Regular Expression / CWE-290 — Authentication Bypass by Spoofing |
| Component | symfony/security-http, X509Authenticator |
| Severity | High (directly vulnerable in mTLS setups) |
Technical analysis — the same class fault in a different component
The X509Authenticator enables client authentication via X.509 certificates (mTLS). Identity extraction from the subject DN happens via a user-configurable regex. As in CVE-2026-45065 (UrlGenerator), the bug sits in unanchored alternations: a typical user pattern such as '^CN=([^,]+)|emailAddress=([^,]+)$' is parsed by the PCRE engine as:
(^CN=([^,]+)) | (emailAddress=([^,]+)$)
When the regex contains three or more alternatives (for example for multi-CA setups), the same problem applies: middle branches are unanchored, substring match suffices. An attacker with a certificate whose DN contains certain substring constellations can impersonate another user.
Additionally: under certain edge cases the Symfony DN parser and the OpenSSL DN parser segment the same DN string differently (RDN ordering, escape character handling, multi-value RDNs) — a differential parser vector, analogous to the HtmlSanitizer URL gap. The fix anchors the regex strictly (same correction as in UrlGenerator: a non-capturing group around the entire alternation) and harmonises the DN parser paths.
Stack mapping
| Stack | Affected? |
|---|---|
| Symfony-direct with X509Authenticator | ✓ |
| Sylius 1.13.x / 2.x | theoretically ✓ — X509Authenticator is not a standard pattern in the typical Sylius frontend |
| TYPO3 v12.4 LTS / v13.4 LTS / v14.x | ✗ — TYPO3 uses its own security layer (\TYPO3\CMS\Core\Authentication), no symfony/security-http |
In the Moselwal estate no customer runs X509Authenticator in production — a test installation has the auth active but is not public. The update is rolled out anyway, because the class insight (unanchored regex alternations) is relevant across the codebase.
Stack mapping — who is really affected?
We make this explicit, because a Symfony wave is not automatically a TYPO3 problem (nor automatically a Sylius problem you fix with composer update sylius/sylius alone). The table below shows which of the seven CVEs arrives in which stack path:
| CVE | Symfony-direct | Sylius 1.13.x / 2.x | TYPO3 v12.4 LTS / v13.4 LTS / v14.x |
|---|---|---|---|
| CVE-2026-45065 UrlGenerator route-requirement bypass | ✓ locale routes, API Platform filters | ✓ {_locale} plus channel constraints | ✗ own routing (PageRouter / Enhancers) |
| CVE-2026-45066 HtmlSanitizer host allowlist bypass | ✓ when HtmlSanitizer + UGC | ✓ customer/admin UGC | ✗ standalone typo3/html-sanitizer library |
| CVE-2026-45064 HtmlSanitizer BiDi override | ✓ as above | ✓ as above | ✗ as above |
| CVE-2026-45753 HtmlSanitizer URL attributes | ✓ as above | ✓ as above | ✗ as above |
Mime\Address CRLF injection | ✓ every new Address($email, $name) with user-input $name | ✓ Customer Mailer, newsletter sender | ✓ FluidEmail / MailMessage / EXT:form email finisher |
| CVE-2024-50340 patch bypass SymfonyRuntime | ✓ FrankenPHP/RoadRunner/Swoole | ✓ FrankenPHP/RoadRunner/Swoole | ✗ own bootstrap |
| X509Authenticator DN regex | ✓ when mTLS | (theoretically) | ✗ own security |
Reading aid per stack layer
For TYPO3 operators: the wave brings exactly one immediate point for you — the CRLF gap in Mime\Address. That applies equally to every currently supported TYPO3 line: v12.4 LTS, v13.4 LTS and v14.x are all affected, because since TYPO3 v10 (Feature-88643) every line runs the mail API via symfony/mailer and symfony/mime. The Composer constraints in typo3/cms-core only pin the Symfony major line (v12 → Symfony 6.4, v13 → 7.x, v14 → 7.x/8.x), the patch version is pulled through normally. That's not “less serious” than Sylius — it's the only gap in the wave that lands directly in your mail pipeline. EXT:form configurations with a user-configurable senderName or own extensions that instantiate new Address(...) with form-field values are directly exploitable. composer update symfony/mime --with-all-dependencies pulls the patch into the Composer lock, vendor/bin/typo3 cache:flush rounds it off. The other six CVEs do not hit TYPO3.
For Sylius operators: all seven CVEs are potentially relevant. Renovate (or a composer update --with-all-dependencies) pulls the patches automatically, because Sylius pins symfony/symfony and the individual components as dependencies. Sylius itself has not published a separate advisory today — the Symfony patches are enough.
For Symfony-direct operators: look at all seven CVEs, prioritise by setup. Locale-routing apps first (CVE-2026-45065), UGC apps with HtmlSanitizer second (CVE-2026-45066 / -45064 / -45753), mail pipelines third (Mime\Address).
Two structural patterns — what the 20 May wave says about Symfony hygiene
Seven CVEs in a day is a lot, but the structural observation is not “Symfony has a problem” but “two class faults appear in parallel across multiple components”:
First: differential parser mismatches. The HtmlSanitizer parses URLs in an RFC-3986-leaning fashion, the browser in WHATWG. The Symfony DN parser segments differently than OpenSSL. parse_str() interprets character classes differently than the SAPI argv layer. Every time a security check happens on a parser representation that does not match the downstream action, a bypass opens up. The clean consequence: for security-relevant parsing paths either use the same parser in the check and the effect step, or run the check redundantly against both parser representations. For Symfony apps concretely: on every URL validation against user input, parse at least once through League\Uri or Rowbot\URL (WHATWG-conformant) instead of relying only on parse_url().
Second: unanchored regex alternations.'#^a|b|c$#' is a classic anti-pattern, because the anchors only grip the rim branches due to PCRE operator precedence. The problem hits UrlGenerator and X509Authenticator simultaneously. The fix in both cases is identical: wrap the alternation construct in a non-capturing group so the anchors sit outside the group — '#^(?:a|b|c)$#'. Anyone writing their own code with regex validation should from today audit every alternation validator against this pattern — also in form validators, in custom slug sanitizers, in their own REST resource allowlists.
The HtmlSanitizer URL gaps combined with the action/formaction oversight show a third, smaller lesson: allowlist-based protection is only as good as the completeness of the allowlist. Anyone running their own sanitizer setups or own URL attribute filters should keep the HTML5 spec URL attribute lists up to date — the list grows with new specs (web components, popover attributes, etc.), the sanitizer does not update automatically.
The CRLF gap in Mime\Address closes the picture. A pattern that has recurred in PHP mailer libraries for 15 years (most prominently in PHPMailer CVE-2016-10033), and which despite Symfony's general robustness has now surfaced once more. Lesson: user input into mail header constructors is always a CRLF-reject duty path — both on the library side (which Symfony corrects today) and on the caller side (defense-in-depth in your own mailer services and form finishers).
Detection and verification
Manual verification per setup type doable in under 20 minutes. The following grep patterns find the typical call sites.
Which Symfony components are installed?
composer show 'symfony/symfony' 'symfony/html-sanitizer' 'symfony/routing' \
'symfony/security-http' 'symfony/mime' 'symfony/runtime' 2>/dev/null
Compare the version column against the fix list above. For TYPO3 setups, specifically check symfony/mime — the other components are pulled transitively, but only Mime matters here.
HtmlSanitizer with allowLinkHosts / allowMediaHosts?
grep -rnE '(allowLinkHosts|allowMediaHosts)\(' src/ config/ 2>/dev/null
Only relevant for Sylius and Symfony-direct apps. Hits in own code paths are a direct CVE-2026-45066 vector.
UrlGenerator routes with alternation requirements?
# Check annotation or attribute routes
grep -rnE '@Route|#\[Route' src/ 2>/dev/null | grep -E 'requirements.*\|'
# Plus all YAML routes
grep -A2 'requirements:' config/routes*.yaml config/routes/*.yaml 2>/dev/null | grep '|'
Hits with de|en|fr-like alternations are a direct CVE-2026-45065 vector. Sylius locale routes are practically guaranteed here.
Mime\Address with user input (Sylius / Symfony-direct)?
grep -rnE 'new\s+(\\?Symfony\\\\Component\\\\Mime\\\\)?Address\s*\(' src/ 2>/dev/null
Every site where a second parameter is built from request data, customer entity properties or form submission values is a direct Mime header injection vector.
TYPO3 EXT:form email finisher with senderName templates?
# Check form definitions (YAML)
grep -rnE 'senderName|senderAddress' \
fileadmin/Forms/ packages/*/Configuration/Yaml/Forms/ \
config/sites/*/Forms/ 2>/dev/null
# Plus EmailFinisher calls in your own PHP code
grep -rnE 'EmailFinisher|MailMessage|FluidEmail' \
packages/*/Classes/ 2>/dev/null
Hits with placeholder templates like {name} or {fullname} in senderName are direct CRLF injection paths.
Cache clear is a duty step
# Symfony / Sylius
bin/console cache:clear --env=prod
# TYPO3
vendor/bin/typo3 cache:flush
# Plus container rebuild on platforms with FrankenPHP / worker modes
Symfony patches often only take effect after cache clear, because the compiled DI containers freeze route and sanitizer configurations. For TYPO3 this concerns the mail configuration more than the UrlGenerator / sanitizer configurations.
Operator recommendation — operational decision block
| Question | Answer → Action |
|---|---|
Do I run symfony/routing with alternation requirements and use the UrlGenerator for external links? | Yes → immediate update to the relevant patch version, plus cache clear, within 24 h. (Sylius/Symfony-direct only — not TYPO3.) |
Do I run symfony/html-sanitizer with UGC and allowLinkHosts/allowMediaHosts? | Yes → update within 24 h plus audit of the sanitizer configuration. (Sylius/Symfony-direct only — not TYPO3.) |
Do I have new Address(...) with user-controlled display names, an EXT:form email finisher with a senderName placeholder or a Sylius Customer Mailer with a customer display name in From? | Yes → update within 24 h plus an explicit CRLF-strip step in the calling code as defense in depth. (Sylius, Symfony-direct and TYPO3 affected.) |
| Do I have X509Authenticator with regex alternations in the DN pattern? | Yes → update within 24 h plus DN regex audit. (Symfony-direct only; Sylius/TYPO3 standard setups irrelevant.) |
| Is my app running on FrankenPHP/RoadRunner/Swoole with SymfonyRuntime? | Update within 72 h plus verification that APP_DEBUG in the production container ENV is explicitly pinned to 0. (Sylius/Symfony-direct only — TYPO3 has its own bootstrap.) |
| I use Renovate-driven containers and I'm a Moselwal customer? | No action needed — the update runs through during the morning, the cache clear is part of the container restart. |
Recommendation per setup type
Single-tenant Symfony or Sylius with Renovate. No operational pressure, rollout runs automatically.
Symfony-direct without Renovate but with Composer mode. Today: composer update 'symfony/*' --with-all-dependencies, followed by bin/console cache:clear --env=prod and worker restart.
Sylius 1.13.x / 2.x. Sylius consumers of the Symfony components inherit the fix automatically once the Symfony patches are in the Composer lock. Renovate MR plus container rebuild is enough. Anyone pinning Sylius constraints explicitly should verify that the pin allows the new Symfony patch versions — Sylius constraints are usually formulated with ^5.4, ^6.4, ^7.4 or ^8.0, which covers today's patches.
TYPO3 v12.4 LTS / v13.4 LTS / v14.x. For TYPO3 exactly one CVE is relevant today: the Mime\Address CRLF gap. composer update symfony/mime --with-all-dependencies (typically also pulls symfony/mailer and transitive Symfony components), then vendor/bin/typo3 cache:flush. Anyone running EXT:form with a user-configurable senderName should add a defense-in-depth step — either extend the form finisher with a CRLF-strip step or pin the senderName in the form definition against a static list via the formvendor override. The other six Symfony CVEs do not hit TYPO3.
Drupal 10+/11. Drupal uses Symfony components as direct dependencies (symfony/routing, symfony/http-foundation, symfony/mime etc.). The HtmlSanitizer wave is largely irrelevant here (Drupal has its own filter systems), the UrlGenerator and Mime gaps can hit. composer update --with-all-dependencies, then drush cr.
How Moselwal handles Symfony waves
For advisory waves like the 20 May Symfony cluster, a three-layer approach makes sense — and that is exactly why Moselwal builds its platforms around auto-update readiness:
Layer 1: patch pipeline picks up all four lines plus the component updates. A version-watcher pipeline (Renovate, Dependabot, Mend) picks up both symfony/symfony 5.4.52 and the individual component bumps (symfony/html-sanitizer, symfony/routing, symfony/security-http, symfony/mime, symfony/runtime) as well as the parallel lines 6.4.40, 7.4.12, 8.0.12. For TYPO3 platforms the symfony/mime bump is the relevant trigger, because it fixes the mail path that has run on symfony/mailer and symfony/mime since TYPO3 v10; platforms with EXT:form configurations and user-configurable senderName in particular are prioritised in the image rebuild.
Layer 2: rolling rebuild prioritised by exposure. Order:
- Sylius platforms with active
allowLinkHostsconfiguration and newsletter pipelines with customer display-name headers. - TYPO3 platforms with EXT:form and user-configurable
senderName. - Symfony-direct apps with locale routing constraints.
- Long tail (everything else).
The FrankenPHP worker restarts are graceful, the Symfony cache clear is integrated into the container rebuild. TYPO3 cache flushes run in the post-deployment hook.
Layer 3: audit pass over the configuration state. In parallel a grep audit runs: are there alternation requirements in route definitions, are there allowLinkHosts/allowMediaHosts in sanitizer configs, are there new Address(...) instantiations with user input in the display name, are there EXT:form definitions with {form-field} placeholders in senderName. The result feeds the next maintenance routine — the cluster is therefore not just “patched away”, but used as an occasion for a systematic configuration review.
Anyone maintaining a Symfony, Sylius or TYPO3 platform who wants to set up a comparable wave routine will find the entry point in the CTA below.
Frequently asked questions about the Symfony disclosure wave from 20 May 2026
Are all seven CVEs directly exploitable, or do they depend on specific setups?+
Three of the seven are directly exploitable as soon as the relevant component sits in the production path (UrlGenerator route bypass on alternation requirements, HtmlSanitizer trio in UGC flows with a host allowlist, Mime\Address CRLF injection in mail pipelines with user display names). The other four (X509Authenticator, SymfonyRuntime bypass, plus the narrower HtmlSanitizer paths without a host allowlist) require specific configurations but are widespread across the classic Symfony setup patterns.
Am I affected as a TYPO3 operator — and does it make a difference whether I'm on v12, v13 or v14?+
Yes, affected via one CVE: the CRLF injection in Symfony\Component\Mime\Address. And no, the TYPO3 major makes no difference to whether you are affected — v12.4 LTS, v13.4 LTS and v14.x are all in the same situation, because since TYPO3 v10 (Feature-88643) every line runs the mail API via symfony/mailer and symfony/mime. FluidEmail and MailMessage require Address objects for every recipient and sender. Concrete problems: EXT:form with a user-configurable senderName, every own extension with new Address($email, $userInput), every customer confirmation mailer with a display name from form data. What differs per TYPO3 line is only the concrete Symfony Mime fix version: v12.4 → symfony/mime 6.4.40, v13.4 → 7.4.12, v14.x → 7.4.12 or 8.0.12. The flow is the same everywhere: composer update symfony/mime --with-all-dependencies plus vendor/bin/typo3 cache:flush. The other six Symfony CVEs do not hit TYPO3.
Is the Symfony patch update enough for Sylius — or do I need to update sylius/sylius separately?+
Sylius pulls the Symfony components as Composer dependencies — today's Symfony wave therefore flows automatically through composer update --with-all-dependencies. Sylius itself has not published a separate advisory in May 2026. Anyone pinning Sylius constraints very tightly (sylius/sylius = 2.1.5) should verify that the pin allows the new Symfony patch versions — Sylius constraints are usually formulated with ^5.4, ^6.4, ^7.4, which covers today's patches.
Am I affected by the UrlGenerator gap if I do not use alternation requirements?+
No — the bug only takes effect on requirements strings that contain | alternations. Anyone using only simple patterns (\d+, [a-z]+, \w{3,}) is not directly exploitable. Apply the update anyway, because a future multi-locale route or a new constraint pattern can activate the problem.
What does the SMTP header injection in Mime\Address mean in practice?+
If your app has a mail pipeline in which From, Reply-To or Sender is built from user input (a newsletter tool with an “on behalf of” function, a customer support forwarder, a form-to-mail plugin), an attacker with a CRLF in the display name could inject additional headers (Bcc: attacker@example, Reply-To: attacker@example, even content-type manipulation) into the outgoing mail. Real-world leverage: spam dispatch via your server, phishing emails with your domain footer, BCC exfiltration of internal mail to attacker mailboxes.
Does Cloudflare WAF protect me from the HtmlSanitizer bypasses?+
To a limited extent. WAFs see the HTTP request layer, but the HtmlSanitizer bypasses happen inside the application process, after the request-layer filters are through. A WAF can block conspicuous BiDi override patterns in URLs as a heuristic, but it is no substitute for the patch.
Do I also need to patch my own code, or is the library update enough?+
The library update is enough for the Symfony/Sylius code paths. Your own code with new Address(...) and user input in the display name benefits from the library correction directly, because the constructor now strictly rejects CRLF (with InvalidArgumentException). Anyone wanting to avoid that (for example because the app sanitises the display name before the mailer call) should still take the patch and keep their own sanitisation as defense in depth. For your own code with regex validation, a targeted audit sweep on unanchored alternations pays off.
Conclusion
Seven CVEs in a day is a lot, but structurally it's two classes plus three single-runners. The classes — differential parser mismatch and unanchored regex alternation — have been known as anti-patterns for years and appear in this wave in parallel across multiple components. The Symfony team appears to have run a systematic audit sweep and disclosed the class clusters jointly. Structurally that's a favourable pattern for operators: one wave, one maintenance window, every relevant component in a single roll-forward.
Important for framing: not every Symfony wave equals a wave for every PHP stack. For TYPO3 operators, exactly one CVE is relevant today — the CRLF injection in Mime\Address, because since TYPO3 v10 (Feature-88643) the mail API runs on symfony/mailer and symfony/mime. That applies equally to v12.4 LTS, v13.4 LTS and v14.x — the TYPO3 major makes no difference to whether you are affected. It is not “less serious” than for Sylius — it is the only gap in the wave that lands directly in the TYPO3 mail pipeline, and it is directly exploitable in EXT:form setups with a user-configurable sender name or in own extensions with new Address($email, $userInput). For Sylius and Symfony-direct operators in turn, all seven CVEs are potentially relevant, because Sylius uses the Symfony full-stack components directly.
For stacks with an auto-update pipeline (Renovate, Dependabot or similar), the fix versions flow into the build without manual intervention and without visible service interruption. For self-hosted setups without an auto-update pipeline, the order above applies: first the HtmlSanitizer trio apps (if UGC is in play), then UrlGenerator apps with regex route requirements, then mail pipelines with user input in address headers (including TYPO3 EXT:form). Cache clear is a duty step after every Symfony patch — the compiled DI containers otherwise keep routing and sanitizer configurations frozen.
Anyone writing their own code with regex validation has two concrete audit tasks today: bring every alternation validator into the '#^(?:a|b|c)$#' pattern, and check every security-relevant parser path so that check phase and effect phase use the same parser representation. Plus a third: check every mailer call site for CRLF rejection before new Address(...) — the library does this now, but defense in depth doesn't hurt.
The interesting question is not when the next Symfony wave will come — it is whether your own codebase carries the same class faults and surfaces them at the next external audit.
This post reflects our technical and strategic assessment. It does not replace your own code review or data protection impact assessment when processing user-submitted content.
Keep your Symfony, Sylius and TYPO3 stack patch-ready?
If you self-host Sylius, a Symfony app, or a TYPO3 installation and find yourself dragged into a manual update shift every time a multi-CVE wave like today's hits, get in touch. We set up Renovate on your stack, define the auto-merge policy by severity, automate container rebuild plus cache clear, and in parallel run the code audit against today's updated class patterns (unanchored regex alternations, differential parser paths, CRLF reject in your own mailer services) — so that next time you only get an email, not a night shift.
We check, mitigate and validate live Symfony, Sylius and TYPO3 platforms. SBOM inventory, Renovate setup, container rebuild in the maintenance window, PoC validation. Platform operations, not consulting-on-paper.

![[Translate to English:] Foto von Kai Ole Hartwig.](/fileadmin/_processed_/e/9/csm_ole-neu_73323ad80d.jpeg)
![[Translate to English:] Eine präzise Reihe gleichartiger Kraftpapier-Pakete auf Beton, zwischen zwei Paketen entweicht ein dünner oxbloodfarbener Staubfaden nach oben; daneben Messingstempel und Lupe im kühlen Nordlicht.](/fileadmin/_processed_/b/7/csm_80c054b74d4e3192c9fd48e5d9456e1fea17ed40a306c4640fd659046bf50e9a_9681f71cee.jpg)