ReDi Restaurant Reservation is a WordPress plugin that provides a restaurant reservation system, where users can make and edit reservations. The admin of the website where the plugin is installed can look at overviews of reservations made. The plugin also provides an external website that the website owner can visit, from a tablet, to view and edit all the reservations for that day. ReDi Restaurant Reservation version 21.0307 and earlier contains an Unauthenticated Stored Cross-Site Scripting (XSS) vulnerability.
How the vulnerability works
Let’s have a bite of this snack! How does this vulnerability work? The plugin provides users the functionality to book a reservation for the restaurant. A user just has to visit the reservation page; it looks like this.
When the reservation form is submitted, a POST request is received by the website. The PHP code below shows how the data in the POST request is processed and saved to local variables. The code shows data is not sanitized or validated before being saved to the variables. However, the UserComments string length is capped at 250 characters.
Next, the saved variables are pushed to the database. Also note here, that variables are not sanitized or validated before being pushed to the database. This means the strings we submit through the form for the variables
UserComments will be saved to the database without changes.
We see the following success alert:
So we submitted the reservation form to the website. How are the submitted variables passing through the code?
When we submitted the form as shown above, a POST request is sent to the server. The PHP code gets the data from the POST request by using GetPost(‘variable’). Below you can see how the variables are set with the data we submitted.
$params array variable gets pushed to the database. Below you can see how the variables are pushed to the database.
The ReDi Restaurant Reservation plugin’s admin menu has a submenu called ‘Upcoming (Tablet PC)’. This is a webpage where you can view the reservations made for a specific time period. This page isn’t a WordPress webpage, but an external page that is loaded within an iframe, as can be seen in the PHP code.
The url that is loaded within the iframe takes the url
https://upcoming.reservationdiary.eu/Entry/ and appends it with the API-key that is registered in your ReDi Restaurant Reservation plugin. When visiting this url, it shows all the made reservations for a specific time period.
The code of the website loaded within an iframe
upcoming.reservationdiary.eu isn’t part of the source code of the plugin. Therefore, I can’t show you in detail how the loading of the reservation works on the webpage. However, when the
This makes it possible for malicious attackers to for example steal the plugin API-key and potentially steal information about customers that made reservations, steal cookies or other sensitive data.
Proof of Concept
The vulnerability exists because the ‘Comment’ message field of the reservation form does not sanitize and validate user input, therefore code can be saved to the database. In addition, the ‘Comment’ field string that is saved in the database is loaded into the webpage without special characters (such as <, >, &, “, and ‘) being converted to HTML entities, which leads to the code being loaded into the webpage. Therefore, the code will be loaded and executed into the webpage where made reservations are listed.
15 April, 2021: WPScan – Vendor contacted
21 April, 2021: WPScan – Escalated to WordPress
25 April, 2021: Vulnerability fixed by vendor
06 May, 2021: WPScan notified me that the disclosure is delayed due to the severity of the vulnerability
10 May, 2021: Disclosure on WPScan and CVE-2021-24299 assigned
23 May, 2021: Proof of Concept disclosure