Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[FrameworkBundle][Mailer] Harden default IP allowlist for Postmark and Brevo webhook parsers#64341

Merged
nicolas-grekas merged 1 commit into
symfony:6.4symfony/symfony:6.4from
nicolas-grekas:harden-mailer-webhook-ip-allowlist-6.4nicolas-grekas/symfony:harden-mailer-webhook-ip-allowlist-6.4Copy head branch name to clipboard
May 23, 2026
Merged

[FrameworkBundle][Mailer] Harden default IP allowlist for Postmark and Brevo webhook parsers#64341
nicolas-grekas merged 1 commit into
symfony:6.4symfony/symfony:6.4from
nicolas-grekas:harden-mailer-webhook-ip-allowlist-6.4nicolas-grekas/symfony:harden-mailer-webhook-ip-allowlist-6.4Copy head branch name to clipboard

Conversation

@nicolas-grekas
Copy link
Copy Markdown
Member

Q A
Branch? 6.4
Bug fix? yes
New feature? no
Deprecations? no
Issues -
License MIT

Both bridges shipped 127.0.0.1 in their default IP allowlist for testing convenience. Brevo's list was also hardcoded inside getRequestMatcher() with no override path, so an operator could not remove the loopback entry short of subclassing. Reaching the loopback entry from off-host requires an integrator-side trust-boundary mistake (a misconfigured trusted-proxy chain accepting X-Forwarded-For: 127.0.0.1, or a co-resident SSRF), so this is hardening rather than a CVE — the framework still shouldn't ship the loopback in the production-default array.

Postmark exposes PROVIDER_IPS as a public const and drops 127.0.0.1 from the default $allowedIPs. Brevo gains the same PROVIDER_IPS const, an $allowedIPs constructor argument (mirroring Postmark), and hash_equals() validation of the Authorization: Basic base64($secret) header — mirroring the Mailjet parser. An empty $secret skips the check, consistent with the rest of the bridges. Brevo's "Secure webhook calls" documentation currently exposes only IP allowlisting, basic-auth-in-URL, bearer-token, and custom-header options, so basic-auth is the spec-aligned signature path today.

To keep local development working out of the box, FrameworkBundle re-adds 127.0.0.1 to the allowlists of mailer.webhook.request_parser.brevo and mailer.webhook.request_parser.postmark when kernel.debug is true. The override is gated by \defined($class.'::PROVIDER_IPS') for BC with older installed bridge versions, and targets the $allowedIPs named argument so the two bridges can keep different ctor signatures. The webhook-parser loop also moved after mailer_webhook.php is loaded so removeDefinition for unavailable bridge packages actually takes effect.

@carsonbot carsonbot added this to the 6.4 milestone May 23, 2026
@carsonbot carsonbot changed the title [Mailer][FrameworkBundle] Harden default IP allowlist for Postmark and Brevo webhook parsers [FrameworkBundle][Mailer] Harden default IP allowlist for Postmark and Brevo webhook parsers May 23, 2026
@nicolas-grekas nicolas-grekas merged commit 62f8aac into symfony:6.4 May 23, 2026
10 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.