HTTP: Preserve non-default port in get_allowed_http_origins()#12338
HTTP: Preserve non-default port in get_allowed_http_origins()#12338dhrupo wants to merge 1 commit into
Conversation
get_allowed_http_origins() built the allowed CORS origin list from the host of admin_url() and home_url() only, dropping any port (there was a '@todo Preserve port?' note). Sites served on a non-default port, such as http://example.com:8080, had their cross-origin requests rejected because the browser Origin header includes the port while the allowed list did not. Append the port to the allowed origins when it is present and non-default. The default HTTP and HTTPS ports (80 and 443) are omitted because browsers leave them out of the Origin header, so an explicit ':80'/':443' in the site URL still produces a port-less origin that matches the request. Adds regression tests covering custom ports, the default-port case, a port-less URL, and is_allowed_http_origin() matching a custom-port origin. Fixes #65522.
|
Hi there! 👋 Thank you for your contribution to WordPress! 💖 It looks like this is your first pull request to No one monitors this repository for new pull requests. Pull requests must be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description. Pull requests are never merged on GitHub. The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making. More information about how GitHub pull requests can be used to contribute to WordPress can be found in the Core Handbook. Please include automated tests. Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the Automated Testing page in the handbook. If you have not had a chance, please review the Contribute with Code page in the WordPress Core Handbook. The Developer Hub also documents the various coding standards that are followed:
Thank you, |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
Summary
Preserve a non-default port in
get_allowed_http_origins()so that sites served on a custom port (for examplehttp://example.com:8080, or a localhttp://localhost:8889) are matched against the browserOriginrequest header.Trac ticket: https://core.trac.wordpress.org/ticket/65522
Problem
get_allowed_http_origins()built the allowed origin list from the host ofadmin_url()andhome_url()only, discarding the port (there was even a// @todo Preserve port?note in core):For a site on
http://localhost:8889, this returnshttp://localhost/https://localhost. The browser sendsOrigin: http://localhost:8889, which is not in the list, so the cross-origin request is rejected.Solution
Append the port when it is present and non-default. The default HTTP and HTTPS ports (80 and 443) are intentionally omitted, because browsers leave them out of the
Originheader — so an explicit:80/:443in the site URL still produces a port-less origin that matches the request.Relationship to #12287
There is an existing PR, #12287, which also appends the port. This PR improves on it in one important way: #12287 appends the port unconditionally, including the default ports. For a site whose
siteurlis stored ashttp://example.com:80, #12287 produces onlyhttp://example.com:80and no port-less variant. Since the browser sendsOrigin: http://example.com(port 80 omitted), that case is broken by #12287 — it would reject a request that currently works on trunk. This PR omits the default ports, so both the custom-port case and the explicit-default-port case are correct. The included tests cover the default-port case explicitly.Testing
Verified on a local install served at
http://localhost:8889:Automated:
New tests cover a custom port, a port-less URL, the explicit default-port case (
:80/:443), andis_allowed_http_origin()matching a custom-port origin.Use of AI Tools
:8889install), identifying the default-port edge case missed by the existing PR, and drafting the change and PHPUnit tests. All changes were reviewed, reproduced in thewordpress-developDocker environment, and verified with PHPUnit and PHPCS by me.