The Wordfence Threat Intelligence team responsibly disclosed several vulnerabilities in Quick Restaurant Menu, a WordPress plugin that allows users to set up restaurant menus on their sites.

This plugin is vulnerable to Missing Authorization, Insecure Direct Object Reference, Cross-Site Request Forgery as well as Cross-Site Scripting in versions up to, and including 2.0.2.

Missing Authorization to Arbitrary Post Deletion

The Quick Restaurant Menu plugin for WordPress is vulnerable to authorization bypass due to a missing capability check on its AJAX actions in versions up to, and including 2.0.2. This makes it possible for authenticated attackers, with subscriber-level permissions and above, to invoke those actions intended for administrator use.

Actions include menu item creation, update and deletion, and other menu management functions. Since the plugin does not verify that a post ID passed to one of its AJAX actions belongs to a menu item, this can lead to arbitrary post deletion/alteration.

Insecure Direct Object Reference

The Quick Restaurant Menu plugin for WordPress is vulnerable to Insecure Direct Object Reference in versions up to, and including, 2.0.2. This is due to the fact that during menu item deletion/modification, the plugin does not verify that the post ID provided to the AJAX action is indeed a menu item. This makes it possible for authenticated attackers, with subscriber-level access or higher, to modify or delete arbitrary posts.

Cross-Site Request Forgery

The Quick Restaurant Menu plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 2.0.2. This is due to missing or incorrect nonce validation on its AJAX actions. This makes it possible for unauthenticated attackers to update menu items, via forged requests granted they can trick a site administrator into performing an action such as clicking on a link.

READ
CERT-In Finds Multiple Bugs in Google Chrome, SAP Products

Quick Restaurant Menu is a plugin offered by ThingsForRestaurants that provides site owners with the ability to create menus for different occasions such as lunch and dinner along with the option to price items differently per menu.

As part of the plugin’s functionality, menu items can be created, deleted and moved around on menus. Dividers can be added to menus to visually separate different menu sections from one another. Menu items are stored as posts with type erm_menu_item.

More specifically, the plugin allows users to arrange menu items for menus via a drag-and-drop method and utilizes AJAX actions to accomplish this. Below is one of those functions in more detail:

Buy Me A Coffee
function erm_delete_menu_item() {
 
    if (isset($_POST['post_id'])) {
        wp_delete_post( absint($_POST['post_id']), true);
        wp_send_json_success();
    }
    exit();
}
add_action( 'wp_ajax_erm_delete_menu_item', 'erm_delete_menu_item' );

The team noticed that this short function checks for the existence of a post_id parameter in the POST request, casts this provided parameter to an integer and then deletes the menu item with this id. This function can be invoked by sending a POST request to /wp-admin/admin-ajax.php that contains the action name as well as a post id.

POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1
Host: 127.0.0.1

action=erm_delete_menu_item&post_id=49

The plugin developers implemented the following fixes:

function erm_delete_menu_item() {
 
    if (!wp_verify_nonce(sanitize_text_field($_REQUEST['nonce']), 'erm_menu_actions' ))
    {
        wp_send_json_error();
    }
 
    if (isset($_POST['post_id'])) {
 
        if (get_post_type(absint($_POST['post_id'])) != 'erm_menu_item')
        {
            wp_send_json_error();
        }
 
        wp_delete_post( absint($_POST['post_id']), true);
        wp_send_json_success();
    }
    exit();
}
add_action( 'wp_ajax_erm_delete_menu_item', 'erm_delete_menu_item' );

By implementing the nonce check

if (!wp_verify_nonce(sanitize_text_field($_REQUEST['nonce']), 'erm_menu_actions' )),

the function now ensures that a proper nonce is set which properly verifies intent and prevents Cross-Site Request Forgery attacks from being successful. The function also performs a post type check before performing the deletion, which fixes the Insecure Direct Object Reference vulnerability that made it possible to delete arbitrary pages and posts. Now a user can only delete posts with the erm_menu_item type.

READ
Total Fitness Data Breach Exposes Nearly 500,000 Images, Including Sensitive Personal Data

One thing to note is that a proper authorization check is still missing. The function does not ensure that the person performing the action has the proper capabilities. However, those are implied through the use of a nonce check.

As long as the nonce is properly verified and an erm_menu_actions nonce cannot be obtained by users other than those intended to perform those actions, it concludes that only properly authorized users should have access to this function.

This is the case in this plugin which makes exploiting the missing authorization impractical. Despite that, we still highly recommend developers ensure capability checks are used as the primary method of authorization control since a nonce could have the potential to be exposed at some point later in development, or by a separate vulnerability.