I’m writing some code that updates options using update_option
using the REST API and apiFetch.
I’m used to doing this using AJAX where I would pass a nonce along in the request to my PHP function, as well as check for current user capabilities.
Using the REST API and apiFetch feels much better than using AJAX, but I feel like I’m missing something when it comes to security.
Here’s an idea of what I’m doing:
register_rest_route(
$namespace,
'/update_settings/',
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_settings' ),
'permission_callback' => array( $this, 'update_settings_permission' ),
)
);
My permission_callback
looks like this:
public function update_settings_permission() {
if ( ! current_user_can( 'manage_options' ) ) {
return $this->error( 'user_dont_have_permission', __( 'You do not have permission to change options.' ) );
}
return true;
}
My update_settings function looks like this:
public function update_settings( WP_REST_Request $request ) {
$new_settings = $request->get_param( 'settings' );
if ( is_array( $new_settings ) ) {
$current_settings = get_option( 'my_options', array() );
update_option( 'my_options', array_merge( $current_settings, $new_settings ) );
}
return $this->success( true );
}
And then the request itself is quite standard:
apiFetch( {
path: 'namespace/v1/update_settings',
method: 'POST',
data: {
settings: this.state.settings,
},
} ).then( ( result ) => {
// all done.
} );
This all works perfectly, but it seems too easy. Should I be passing a nonce along somewhere? It seems like apiFetch has some middlewares that include a nonce – is this all done for us by default?
1 Answer
This all works perfectly, but it seems too easy. Should I be passing a nonce along somewhere?
No
It seems like apiFetch has some middlewares that include a nonce – is this all done for us by default?
Yes.
If your endpoint requires a nonce and apiFetch
did not provide it, then apiFetch
would not work. Authenticated endpoints using cookie based auth require nonces.
Remember, the REST API authentication and security is server side. apiFetch
is client side. apiFetch
cannot magically bypass the server side checks unless you deliberately added such a bypass. If you had, you would know about it and you would not have asked this question, as that would require a considerable amount of effort and intention to do.
There are security issues here, but they are unrelated to apiFetch
. The use of apiFetch
has not reduced your security.