Make WordPress Core

Opened 10 hours ago

#66652 new defect (bug)

Lack of type checking in posts API can trigger fatal error

Reported by: leedxw Owned by:
Priority: normal Milestone: Awaiting Review
Component: REST API Version: 7.1.4
Severity: normal Keywords:
Cc: Focuses:

Description

An attacker is triggering fatal errors on one of our sites using a mechanism that can be reproduced with:

curl -v -X POST -d "template[]=" "http://localhost/wp-json/wp/v2/posts"
PHP Fatal error:  Uncaught TypeError: Cannot access offset of type array in isset or empty in /var/www/html/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php:1663
 Stack trace:
 #0 /var/www/html/wp-includes/rest-api/class-wp-rest-request.php(948): WP_REST_Posts_Controller->check_template()
 #1 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(1115): WP_REST_Request->has_valid_params()
 #2 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(441): WP_REST_Server->dispatch()
 #3 /var/www/html/wp-includes/rest-api.php(488): WP_REST_Server->serve_request()
 #4 /var/www/html/wp-includes/class-wp-hook.php(353): rest_api_loaded()
 #5 /var/www/html/wp-includes/class-wp-hook.php(377): WP_Hook->apply_filters()
 #6 /var/www/html/wp-includes/plugin.php(571): WP_Hook->do_action()
 #7 /var/www/html/wp-includes/class-wp.php(418): do_action_ref_array()
 #8 /var/www/html/wp-includes/class-wp.php(822): WP->parse_request()
 #9 /var/www/html/wp-includes/functions.php(1352): WP->main()
 #10 /var/www/html/wp-blog-header.php(16): wp()
 #11 /var/www/html/index.php(17): require('...')
 #12 {main}
   thrown in /var/www/html/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php on line 1663

A possible fix is to use is_string()

--- wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php.dist      2026-11-10 10:26:33.000000000 +0000
+++ wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php   2026-11-10 16:43:27.490236201 +0000
@@ -1660,7 +1660,7 @@
                // If this is a create request, get_post() will return null and wp theme will fallback to the passed post type.
                $allowed_templates = wp_get_theme()->get_page_templates( $post, $this->post_type );

-               if ( isset( $allowed_templates[ $template ] ) ) {
+               if ( is_string( $template ) && isset( $allowed_templates[ $template ] ) ) {
                        return true;
                }

Change History (0)

Note: See TracTickets for help on using tickets.