Repository navigation
Conversation
wp_ajax_find_posts() queried with 'post_status' => 'any' and no 'perm',
so any user able to open the media library ('upload_files') could read the
titles of other users' private and draft posts through the "Find Posts"
modal. With 'any', WP_Query skips the 'perm' author restriction entirely.
Pass 'perm' => 'editable' and an explicit status list so the query is
limited to posts the current user may edit, which is what the modal is for
(attaching media to an editable post). Users who can edit others' posts are
unaffected.
Add ajax tests covering the private and draft leak, that the user's own
posts are still listed, and that an editor still sees private posts.
See #40340.
|
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. |
Trac ticket: https://core.trac.wordpress.org/ticket/40340
Problem
wp_ajax_find_posts()(the "Find Posts" / "Attach to existing content" modal)queries with
'post_status' => 'any'and no'perm':The only gate on the handler is
check_ajax_referer( 'find-posts' ), and thatnonce is available to anyone who can open the media library (
upload_files,i.e. Author and up). As a result, a low-privileged user can read the titles
of other users' private and draft posts by searching in this modal.
The
'perm'author restriction inWP_Queryis never applied when the statusis
'any'(it is only evaluated in the per-status branch), which is thebehavior johnbillion already noted in comment:6 of #40340.
Fix
Pass
'perm' => 'editable'and an explicit status list so the query engagesthe author restriction and only returns posts the current user may actually
edit — which is what the modal is for (attaching media to an editable post):
Users who can edit others' posts (Editor, Administrator) are unaffected and
still see all matching posts.
Tests
Adds
tests/phpunit/tests/ajax/wpAjaxFindPosts.phpcovering:Verified locally: the two disclosure tests fail on
trunkand pass with thischange.
phpcsis clean on both files.Note for reviewers
'perm' => 'editable'narrows the modal to editable posts. This matches itspurpose, but it is a behavior change worth confirming: custom post statuses
registered by plugins are no longer included (the previous
'any'included anystatus not marked
exclude_from_search). Happy to adjust the status list ifpreferred.
See #40340.
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code, with code-intruder (my own static analysis tool)
Model(s): Claude Opus, Claude Haiku
Used for: code-intruder flagged the handler as reachable without a capability
check (only a nonce guards it) and an AI review triaged the finding. AI helped
reproduce it on a local multisite install (as an Author, searching returned
another user's private/draft post title) and write the test. I reviewed and
tested the change myself.