Repository navigation
REST API, Meta: Only check meta authorization when a value changes. - #14328
DevinWalker wants to merge 3 commits into
Conversation
When a post is saved, the block editor sends back every registered meta field it received, including fields the current user is not allowed to edit. [56075] stopped checking authorization for single values that match the stored value, but a save still failed with a 403 when the request included: * The default value of a field with no stored value. Since [58831] compares against the raw stored value, this also fails when a default is registered. * The unchanged values of a multi field, because authorization was checked before the values were compared. * An empty list or `null` for a field with no stored value, which goes through the delete path and its authorization check. Authorization is now only checked when a value would change. Users who can edit a field still store its default value, as introduced in [58831]. Follow-up to [56075], [58831]. See #48426.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. 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. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
|
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. |
When a post is saved in the block editor, it sends back every registered meta field it got from the REST API, including fields the current user isn't allowed to edit. If one of those fields hits the authorization check, the whole save fails with "Sorry, you are not allowed to edit the X custom field." even though the user never touched that field.
56075 fixed this for single fields that already have a stored value. These cases still fail on trunk:
nullfor a field with no stored value. That goes through the delete path, which checked authorization before checking if there was anything to delete.What changed
All in
WP_REST_Meta_Fields, so it covers post, term, comment and user meta:update_meta_value(): when the user can't edit the field, nothing is stored, and the value matches the default the API returns for it, the update is skipped instead of returning a 403.update_multi_meta_value(): works out what would be added and removed first, returns early when nothing changes, and only checks authorization when something does. The same default check applies.delete_meta_value(): returns early when nothing is stored, before the authorization check.is_meta_value_same_as_default_value()helper that mirrors whatget_value()returns for a field with no stored value.Users who can edit a field still store the default value, so the 6.7 behavior from #55600 doesn't change. Changing a protected field still returns a 403.
Testing
New tests in
tests/phpunit/tests/rest-api/rest-post-meta-fields.php(--group 48426, 21 cases). 8 of them check that changing a protected field is still rejected, so they pass on trunk too.--group 48426, single site--group 48426, multisite--group restapi, single site--group restapi, multisite--group meta, single site / multisiteThe
restapiruns have 4 warnings (test_get_items_wdotorg_unavailable,test_create_item_wdotorg_unreachableand the twotest_format_validation_is_applied_if_missing_typetests). They show up on trunk too and aren't related to this change.PHPCS and PHPStan are clean on the changed files.
I also checked it in the block editor with Playwright on a local wordpress-develop site, using the mu-plugin below. On trunk the save fails, with the patch it saves.
Manual testing
wp.data.dispatch( 'core/editor' ).editPost( { meta: { _demo_note: 'Changed' } } );_demo_noteis stored.Screenshots
Trac ticket: https://core.trac.wordpress.org/ticket/48426
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Finding the ticket, tracing the cause, writing the fix and the PHPUnit tests, the Playwright check, and drafting this description. I reviewed the code and the test results before opening this PR.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.