apiFetch security

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
1

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.

Leave a Comment