Skip to content

[UPMERGE] 5.0 -> 5.1 - #3181

Merged
dpfaffenbauer merged 13 commits into
5.1from
upmerge/5.0_5.1
Aug 24, 2026
Merged

[UPMERGE] 5.0 -> 5.1#3181
dpfaffenbauer merged 13 commits into
5.1from
upmerge/5.0_5.1

Conversation

@dpfaffenbauer

@dpfaffenbauer dpfaffenbauer commented Aug 24, 2026

Copy link
Copy Markdown
Member

Upmerge of 5.0 into 5.1.

Remember! The upmerge should always be merged with the Merge pull request button.

Refreshed after #3183 ([UPMERGE] 4.1 -> 5.0) merged, so this now carries the open-redirect security fix as well as the Messenger fix.

What it carries forward

Security-relevant files carried by this merge

All merged verbatim — nothing had to be adapted:

file role
ResourceBundle/Controller/RedirectUrlValidationTrait.php new — the single validateRedirectUrl() implementation (rejects dangerous schemes/special characters, scopes the authority check)
CoreBundle/Security/ShopUserAuthenticationSuccessHandler.php new — validates the post-login redirect target
CoreBundle/Security/ShopUserAuthenticationFailureHandler.php new — reads the failure path from the request bags directly
CoreBundle/Resources/config/services/handler.yml wires both handlers (@security.http_utils, @http_kernel)
CoreBundle/Resources/config/pimcore/security.yml registers them as success_handler / failure_handler on the shop firewall
FrontendBundle/Controller/{Cart,Customer,Frontend,Register,Security}Controller.php consume the trait instead of trusting _redirect
StorageListBundle/Controller/StorageListController.php same
features/ui/frontend/account/login.feature, Behat/Context/Ui/Frontend/LoginContext.php regression coverage

All three new classes are present on the merged tree (verified by path, not just by diff).

Conflicts

None — the merge applied cleanly, zero conflicted files.

Verification

Net diff against 5.1 is exactly #2963's 13 files plus #3179's 2, and nothing else:

 features/ui/frontend/account/login.feature         |  7 ++
 .../Behat/Context/Ui/Frontend/LoginContext.php     |  8 ++
 .../Resources/config/pimcore/security.yml          |  2 +
 .../Resources/config/services/handler.yml          |  9 +++
 .../ShopUserAuthenticationFailureHandler.php       | 72 ++++++++++++++++++
 .../ShopUserAuthenticationSuccessHandler.php       | 41 ++++++++++
 .../FrontendBundle/Controller/CartController.php   | 14 +++-
 .../Controller/CustomerController.php              |  8 +-
 .../Controller/FrontendController.php              |  3 +
 .../Controller/RegisterController.php              |  7 +-
 .../Controller/SecurityController.php              | 21 +++++-
 .../Messenger/FailedMessageDetails.php             |  2 +-
 .../Resources/public/pimcore/js/list.js            |  2 +-
 .../Controller/RedirectUrlValidationTrait.php      | 87 ++++++++++++++++++++++
 .../Controller/StorageListController.php           | 10 ++-
 15 files changed, 284 insertions(+), 9 deletions(-)
  • security.yml did not overwrite 5.1's version. The file touched is CoreBundle/Resources/config/pimcore/security.yml (the shop firewall). Diffed against 5.1's committed copy, the merged result adds exactly the two handler lines and changes nothing else.
  • The root config/packages/security.yaml is not touched, so Fix typo in coreshop.security.frontend_regex breaking the pimcore-studio exclusion #3164's corrected coreshop.security.frontend_regex (^/(?!admin|pimcore-studio)[^/]*) is untouched — confirmed by reading it back off the merged tree.
  • No duplication: exactly one validateRedirectUrl() definition on the merged tree.
  • Messenger: drop the redundant failedAt field from MessengerFailedMessage #3180 preserved: the redundant failedAt field is still absent from MessengerFailedMessage, so the TypeScript cleanup already on 5.1 is not reverted.
  • Root composer.json: not touched; replace set equality holds — 66 split packages, 66 entries, missing [], extra [].
  • Split-package branch-value invariant: checked=66 bad=0 (siblings ^5.1, both branch-alias keys at 5.1-dev).
  • No files under any Resources/public/studio/ touched.
  • php -l clean on every changed PHP file.

Ordering

Merge order for this round: #3183 (merged) → this PR#3182 ([UPMERGE] 5.1 -> 2026.x). #3182 must be refreshed once this lands, so that #2963 and #3179 reach 2026.x.

Copilot AI and others added 10 commits January 29, 2026 11:44
Co-authored-by: dpfaffenbauer <5981845+dpfaffenbauer@users.noreply.github.com>
…haracters

Co-authored-by: dpfaffenbauer <5981845+dpfaffenbauer@users.noreply.github.com>
…duplication

Co-authored-by: dpfaffenbauer <5981845+dpfaffenbauer@users.noreply.github.com>
The "@" rejection tested the whole URL, so a same-host redirect carrying an
"@" in its query or fragment was silently downgraded to the default. It now
looks at the parsed authority only, which also makes the preceding user check
meaningful instead of redundant. Backslashes and control characters are now
rejected for absolute URLs as well, not just for relative ones.

Beyond the "_redirect" parameter, the login form feeds "_target_path" and
"_failure_path" to Symfony, which accepts any value starting with "/" or
"http". Both are now run through the same allow-list, in the controller that
renders the form and in a success/failure handler pair, so a target that is
neither a relative path nor a same-host URL falls back to the configured
default. The success handler covers the Referer as well, which the firewall
uses via use_referer.
Psalm rejects calls into @internal Symfony code. The rejected failure path is
now read through the public Request API, and the redirect the parent handler
produced is validated as well, which also covers a failure path configured as
a nested parameter.
Symfony marks Request::get() as internal as well, which Psalm rejects, so the
parameter is looked up in the attribute, query and request bags instead.
FailedMessageDetails::jsonSerialize() emitted "failedAt" while every consumer -
the classic grid column and the Studio MessengerFailedGrid - reads "failed_at",
and the DTO itself already declares #[SerializedName(\"failed_at\")]. Because
JsonSerializableNormalizer outranks ObjectNormalizer in the framework
serializer, jsonSerialize() decides the payload keys and that attribute never
took effect, so the column was empty for every transport.

Emit "failed_at" instead, which makes the existing attribute true rather than
dead code, and align the classic store field with it. The Studio grid already
reads "failed_at" and needs no change.
Messenger: fix empty "Failed At" column by emitting the key the UI reads
Fix open redirect vulnerabilities in redirect parameter handling
@sonarqubecloud

Copy link
Copy Markdown

@dpfaffenbauer dpfaffenbauer added this to the 5.1.0-beta.1 milestone Aug 24, 2026
@dpfaffenbauer dpfaffenbauer self-assigned this Aug 24, 2026
@dpfaffenbauer
dpfaffenbauer merged commit e2bb61e into 5.1 Aug 24, 2026
131 of 133 checks passed
@dpfaffenbauer
dpfaffenbauer deleted the upmerge/5.0_5.1 branch August 24, 2026 13:47
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants