Pages: require authentication and a capability to render generated standalone pages - #82254
Pages: require authentication and a capability to render generated standalone pages#82254shameemreza wants to merge 3 commits into
Conversation
The page.php template hooks an interceptor to admin_init that renders the full page whenever the page query arg matches, with no capability check. Since admin-post.php fires admin_init for logged-out requests, every generated standalone page was served to anonymous visitors. Guard the interceptor with auth_redirect() and current_user_can(), using a new capability page setting in the wp-build config that defaults to manage_options. The font-library page declares edit_theme_options to match its Core menu registration. Fixes WordPress#82251
|
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @shameemreza! In case you missed it, we'd love to have you join us in our Slack community. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
The changelog CI check requires the Unreleased entry to link the current PR rather than the issue it fixes.
|
The other pages (site-editor-v2, theme-preview, media-editor) inherit the manage_options default while their wp-admin counterparts use edit_theme_options, switch_themes, and upload_files respectively. site-editor-v2 is the one that can bite: the Appearance → Design submenu (registered with edit_theme_options) is rewritten to point at it, so a custom role with that capability but not manage_options would see the menu item and get a 403. Worth declaring "capability" for these in package.json too, either here or as a follow-up. WDYT? |
The site-editor-v2, media-editor, and theme-preview pages inherited the manage_options default, while their menu registrations use edit_theme_options, upload_files, and switch_themes. A user holding the menu capability but not manage_options would see the menu entry and get a 403. Declare the matching capability for each. The dashboard and guidelines pages have no menu registration and the experiments page registers with manage_options, so the default already matches those three.
|
Thanks @youknowriad and you're right; I only checked font-library's menu registration and left everything else on the default. Went through each one now: theme-preview registers with I'd rather fix it here than in a follow-up since it's three lines of config, so I declared the matching capability for all three in 768452f. experiments already registers with manage_options, and dashboard and guidelines have no menu registration at all, so the default covers those three fine. |
|
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
@youknowriad The Playwright 8 failure is the image drag-and-drop test tracked as a flaky test in #50325, not related to this change. I don't have permission to rerun the job, so leaving it to whoever picks this up. :) |
What?
Closes #82251.
Adds an authentication and capability guard to the standalone page template in
@wordpress/build, so generated pages such asfont-libraryandoptions-connectorsno longer render for logged-out visitors.Why?
The
page.phptemplate hooks an interceptor toadmin_initand renders the full page whenever thepagequery arg matches, with no capability check.admin-post.phpfiresadmin_initfor logged-out requests to supportadmin_post_nopriv_actions, so any anonymous visitor could load/wp-admin/admin-post.php?page=font-libraryand receive the page shell, block editor scripts, and REST preload data. Reported in #82251 and in core as https://core.trac.wordpress.org/ticket/66001.How?
page.php.templatenow callsauth_redirect()for logged-out visitors andwp_die()with a 403 status for users without the required capability, before rendering anything.wpPlugin.pagesaccept a new optionalcapabilityfield, defaulting tomanage_options. The build emits it through a new{{CAPABILITY}}placeholder.font-librarydeclaresedit_theme_optionsto match the capability Core uses when registering the Fonts menu entry.page-wp-admin.php.templateis unchanged: it renders throughadd_menu_page()andadd_submenu_page()callbacks, which already enforce the menu capability.Testing Instructions
npm run build.build/pages/font-library/page.phpguards the interceptor withis_user_logged_in()andcurrent_user_can( 'edit_theme_options' )./wp-admin/admin-post.php?page=font-library.wp-login.phpwith an empty body. Previously: HTTP 200 with about 21 KB of rendered editor markup.Unit test:
npm run test:unit -- packages/wp-build/lib/test/php-generator.js.Testing Instructions for Keyboard
Not applicable. The change adds no UI; it only gates whether the page renders.
Use of AI Tools
AI assistance: Yes.
Tool: Claude Code.
Used for: reproducing the bug, tracing the cause, and drafting the patch and tests. I reviewed and tested everything before submitting.