Web & Software Developer

WP REST API custom endpoint: only allow access from AJAX on own domain

This is a way to discourage direct access to your custom WP REST API endpoint. It will disallow access from other sites to your endpoint, whether they are using AJAX or wp_remote_get, or similar. It will also disallow direct access from anyone navigating directly to the endpoint in a browser.

Basically, it will only allow AJAX requests from the same domain/site.

This is great to use in a plugin because it is non-intrusive, meaning it does not disable the core WP REST API endpoints, or any other plugin’s custom endpoints. It will only effect your own custom endpoint. This is better than manipulating CORS headers (rest_send_cors_headers()) because you don’t want to break functionality that another plugin may be using.

Note: I say discourage and disallow, but this does not prevent a malicious actor from spoofing the $_SERVER['HTTP_X_REQUESTED_WITH']. This should not be relied upon as a security measure for any sensitive data. This is just a good deterrent for most average WordPress sites that are using the WP REST API for non-sensitive things.

 

This works by adding a permission_callback to the register_rest_route function. This assumes you are registering your custom endpoint with register_rest_route. The permission_callback on lines 10–15 is what makes this work.

Mandatory steps:

  • On line 5, change myplugin/v1 to your own custom REST API namespace, and change /myroute to your own endpoint.
  • On line 8, change myplugin_custom_callback to your own custom REST API callback function name.

// Register a custom WP REST API endpoint

add_action( 'rest_api_init', function () {

	register_rest_route( 'myplugin/v1', '/myroute', array(

		'methods' => 'GET',
		'callback' => 'myplugin_custom_callback',

		'permission_callback' => function () {

			// Disallow direct access, only allow ajax from own domain
			return ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) === 'xmlhttprequest' );

		}

	) );

} );

By

Questions and Comments are Welcome

Your email address will not be published. All comments will be moderated.

Please wrap code in "code" bracket tags like this:

[code]

YOUR CODE HERE 

[/code]