REPORT / 01
Analysis Report · Folder Analysis cache/calendar_1.3.16 → cache/calendar_1.3.17 — CVE-2025-14548
Shared security patch analysis results
02 ·
Lifecycle actions
cancel · resume · skip · regenerate
03 ·
Share this analysis
copy link · embed report
03 ·
CVE Security Analysis & Writeups
ai-generated · per cve
Comprehensive security analysis generated by AI for each confirmed CVE match. Click on a CVE to view the detailed writeup including vulnerability background, technical details, patch analysis, and PoC guide.
CVE-2025-14548
NVD
AI-Generated Analysis
05 ·
Findings
filter · search · paginate
Showing 0 to 0 of 0 results
calendar.php
AI: 7 vulnerabilities
1 false positive, 6 true positives
CVE-2025-14548
--- cache/calendar_1.3.16/calendar.php 2025-12-24 00:33:53.638234872 +0000+++ cache/calendar_1.3.17/calendar.php 2025-12-24 00:33:56.474410430 +0000@@ -7,7 +7,7 @@ Author URI: http://www.kieranoshea.com Text Domain: calendar Domain Path: /languages-Version: 1.3.16+Version: 1.3.17 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html */@@ -35,7 +35,7 @@ // Enable internationalisation function calendar_load_text_domain() { $plugin_dir = plugin_basename(dirname(__FILE__));- load_plugin_textdomain('calendar', false, $plugin_dir . '/languages');+ load_plugin_textdomain('calendar', false, $plugin_dir . '/languages'); // phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound } add_action('plugins_loaded', 'calendar_load_text_domain'); @@ -278,7 +278,7 @@ // then it is upgraded. // Lets see if this is first run and create us a table if it is!- global $initial_style;+ global $calendar_initial_style; // Version info $calendar_version_option = 'calendar_version';@@ -286,7 +286,7 @@ // All this style info will go into the database on a new install // This looks nice in the TwentyTen theme- $initial_style = " .calnk a:hover {+ $calendar_initial_style = " .calnk a:hover { background-position:0 0; text-decoration:none; color:#000000;@@ -529,7 +529,7 @@ calendar_create_calendar_table(); calendar_create_calendar_config_table(); calendar_insert_config_value('can_manage_events','edit_posts');- calendar_insert_config_value('calendar_style',$initial_style);+ calendar_insert_config_value('calendar_style',$calendar_initial_style); calendar_insert_config_value('display_author','false'); calendar_insert_config_value('display_jump','false'); calendar_insert_config_value('display_todays','true');@@ -542,7 +542,7 @@ calendar_add_author_and_description_to_calendar_table(); calendar_create_calendar_config_table(); calendar_insert_config_value('can_manage_events','edit_posts');- calendar_insert_config_value('calendar_style',$initial_style);+ calendar_insert_config_value('calendar_style',$calendar_initial_style); calendar_insert_config_value('display_author','false'); calendar_insert_config_value('display_jump','false'); calendar_insert_config_value('display_todays','true');@@ -557,7 +557,7 @@ calendar_insert_config_value('enable_categories','false'); calendar_add_link_and_category_to_calendar_table(); calendar_create_calendar_categories();- calendar_update_config_value('calendar_style',$initial_style);+ calendar_update_config_value('calendar_style',$calendar_initial_style); } // We've installed/upgraded now, just need to ensure the correct charsets calendar_db_set_charset_for_table(WP_CALENDAR_TABLE);@@ -655,7 +655,7 @@ // The event edit form for the manage events admin page function calendar_events_edit_form($mode='add', $event_id=false) {- global $users_entries;+ global $calendar_users_entries; $data = false; if ( $event_id !== false )@@ -676,15 +676,15 @@ $data = $data[0]; } // Recover users entries if they exist; in other words if editing an event went wrong- if (!empty($users_entries))+ if (!empty($calendar_users_entries)) {- $data = $users_entries;+ $data = $calendar_users_entries; } } // Deal with possibility that form was submitted but not saved due to error - recover user's entries here else {- $data = $users_entries;+ $data = $calendar_users_entries; } ?>@@ -859,11 +859,11 @@ <?php esc_html_e('Repeats for','calendar'); ?> <input type="text" name="event_repeats" class="input" size="1" value="<?php echo esc_attr($repeats); ?>" /> <select name="event_recur" class="input">- <option class="input" <?php echo esc_attr($selected_s); ?> value="S"><?php esc_html_e('None') ?></option>- <option class="input" <?php echo esc_attr($selected_w); ?> value="W"><?php esc_html_e('Weeks') ?></option>- <option class="input" <?php echo esc_attr($selected_m); ?> value="M"><?php esc_html_e('Months (date)') ?></option>- <option class="input" <?php echo esc_attr($selected_u); ?> value="U"><?php esc_html_e('Months (day)') ?></option>- <option class="input" <?php echo esc_attr($selected_y); ?> value="Y"><?php esc_html_e('Years') ?></option>+ <option class="input" <?php echo esc_attr($selected_s); ?> value="S"><?php esc_html_e('None','calendar') ?></option>+ <option class="input" <?php echo esc_attr($selected_w); ?> value="W"><?php esc_html_e('Weeks','calendar') ?></option>+ <option class="input" <?php echo esc_attr($selected_m); ?> value="M"><?php esc_html_e('Months (date)','calendar') ?></option>+ <option class="input" <?php echo esc_attr($selected_u); ?> value="U"><?php esc_html_e('Months (day)','calendar') ?></option>+ <option class="input" <?php echo esc_attr($selected_y); ?> value="Y"><?php esc_html_e('Years','calendar') ?></option> </select><br /> <?php esc_html_e('Entering 0 means forever. Where the recurrance interval is left at none, the event will not reoccur.','calendar'); ?> </td>@@ -881,7 +881,7 @@ // to deal with posts function calendar_edit() {- global $current_user, $users_entries;+ global $current_user, $calendar_users_entries; // First some quick cleaning up $edit = $create = $save = $delete = false;@@ -889,21 +889,21 @@ // Deal with adding an event to the database if ( isset($_REQUEST['action']) && $_REQUEST['action'] == 'add' ) {- if (wp_verify_nonce($_POST['_wpnonce'],'calendar-add') == false) {+ if (!isset($_POST['_wpnonce']) || wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])),'calendar-add') == false) { ?> <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("Security check failure, try adding the event again",'calendar'); ?></p></div> <?php } else { // Set the variables from source input after nonce verification- $title = !empty($_REQUEST['event_title']) ? stripslashes($_REQUEST['event_title']) : '';- $desc = !empty($_REQUEST['event_desc']) ? stripslashes($_REQUEST['event_desc']) : '';- $begin = !empty($_REQUEST['event_begin']) ? $_REQUEST['event_begin'] : '';- $end = !empty($_REQUEST['event_end']) ? $_REQUEST['event_end'] : '';- $time = !empty($_REQUEST['event_time']) ? $_REQUEST['event_time'] : '';- $recur = !empty($_REQUEST['event_recur']) ? $_REQUEST['event_recur'] : '';- $repeats = !empty($_REQUEST['event_repeats']) ? $_REQUEST['event_repeats'] : '';- $category = !empty($_REQUEST['event_category']) ? $_REQUEST['event_category'] : '';- $linky = !empty($_REQUEST['event_link']) ? $_REQUEST['event_link'] : '';+ $title = !empty($_REQUEST['event_title']) ? wp_kses_post(wp_unslash($_REQUEST['event_title'])) : '';+ $desc = !empty($_REQUEST['event_desc']) ? wp_kses_post(wp_unslash($_REQUEST['event_desc'])) : '';+ $begin = !empty($_REQUEST['event_begin']) ? wp_kses_post(wp_unslash($_REQUEST['event_begin'])) : '';+ $end = !empty($_REQUEST['event_end']) ? wp_kses_post(wp_unslash($_REQUEST['event_end'])) : '';+ $time = !empty($_REQUEST['event_time']) ? wp_kses_post(wp_unslash($_REQUEST['event_time'])) : '';+ $recur = !empty($_REQUEST['event_recur']) ? wp_kses_post(wp_unslash($_REQUEST['event_recur'])) : '';+ $repeats = !empty($_REQUEST['event_repeats']) ? wp_kses_post(wp_unslash($_REQUEST['event_repeats'])) : '';+ $category = !empty($_REQUEST['event_category']) ? wp_kses_post(wp_unslash($_REQUEST['event_category'])) : '';+ $linky = !empty($_REQUEST['event_link']) ? wp_kses_post(wp_unslash($_REQUEST['event_link'])) : ''; // Perform some validation on the submitted dates - this checks for valid years and months $date_format_one = '/^([0-9]{4})-([0][1-9])-([0-3][0-9])$/';@@ -1019,7 +1019,7 @@ } else {- do_action('add_calendar_entry', 'add');+ do_action('calendar_add_entry', 'add'); ?> <div class="updated"><p><?php esc_html_e('Event added. It will now show in your calendar.','calendar'); ?></p></div> <?php@@ -1028,31 +1028,31 @@ else { // The form is going to be rejected due to field validation issues, so we preserve the users entries here- $users_entries = new stdClass();- $users_entries->event_title = $title;- $users_entries->event_desc = $desc;- $users_entries->event_begin = $begin;- $users_entries->event_end = $end;- $users_entries->event_time = $time;- $users_entries->event_recur = $recur;- $users_entries->event_repeats = $repeats;- $users_entries->event_category = $category;- $users_entries->event_link = $linky;+ $calendar_users_entries = new stdClass();+ $calendar_users_entries->event_title = $title;+ $calendar_users_entries->event_desc = $desc;+ $calendar_users_entries->event_begin = $begin;+ $calendar_users_entries->event_end = $end;+ $calendar_users_entries->event_time = $time;+ $calendar_users_entries->event_recur = $recur;+ $calendar_users_entries->event_repeats = $repeats;+ $calendar_users_entries->event_category = $category;+ $calendar_users_entries->event_link = $linky; } } } // Permit saving of events that have been edited else if ( isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit_save' ) {- $title = !empty($_REQUEST['event_title']) ? stripslashes($_REQUEST['event_title']) : '';- $desc = !empty($_REQUEST['event_desc']) ? stripslashes($_REQUEST['event_desc']) : '';- $begin = !empty($_REQUEST['event_begin']) ? $_REQUEST['event_begin'] : '';- $end = !empty($_REQUEST['event_end']) ? $_REQUEST['event_end'] : '';- $time = !empty($_REQUEST['event_time']) ? $_REQUEST['event_time'] : '';- $recur = !empty($_REQUEST['event_recur']) ? $_REQUEST['event_recur'] : '';- $repeats = !empty($_REQUEST['event_repeats']) ? $_REQUEST['event_repeats'] : '';- $category = !empty($_REQUEST['event_category']) ? $_REQUEST['event_category'] : '';- $linky = !empty($_REQUEST['event_link']) ? $_REQUEST['event_link'] : '';+ $title = !empty($_REQUEST['event_title']) ? wp_kses_post(wp_unslash($_REQUEST['event_title'])) : '';+ $desc = !empty($_REQUEST['event_desc']) ? wp_kses_post(wp_unslash($_REQUEST['event_desc'])) : '';+ $begin = !empty($_REQUEST['event_begin']) ? wp_kses_post(wp_unslash($_REQUEST['event_begin'])) : '';+ $end = !empty($_REQUEST['event_end']) ? wp_kses_post(wp_unslash($_REQUEST['event_end'])) : '';+ $time = !empty($_REQUEST['event_time']) ? wp_kses_post(wp_unslash($_REQUEST['event_time'])) : '';+ $recur = !empty($_REQUEST['event_recur']) ? wp_kses_post(wp_unslash($_REQUEST['event_recur'])) : '';+ $repeats = !empty($_REQUEST['event_repeats']) ? wp_kses_post(wp_unslash($_REQUEST['event_repeats'])) : '';+ $category = !empty($_REQUEST['event_category']) ? wp_kses_post(wp_unslash($_REQUEST['event_category'])) : '';+ $linky = !empty($_REQUEST['event_link']) ? wp_kses_post(wp_unslash($_REQUEST['event_link'])) : ''; if ( !isset($_REQUEST['event_id']) ) {@@ -1060,7 +1060,7 @@ <div class="error"><p><strong><?php esc_html_e('Failure','calendar'); ?>:</strong> <?php esc_html_e("You can't update an event if you haven't submitted an event id",'calendar'); ?></p></div> <?php }- elseif (wp_verify_nonce($_POST['_wpnonce'],'calendar-edit_save_'.$_REQUEST['event_id']) == false) {+ elseif (wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])),'calendar-edit_save_'.sanitize_text_field(wp_unslash($_REQUEST['event_id']))) == false) { ?> <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("Security check failure, try editing the event again",'calendar'); ?></p></div> <?php@@ -1171,7 +1171,7 @@ if (isset($start_date_ok) && isset($end_date_ok) && isset($time_ok) && isset($url_ok) && isset($title_ok) && isset($recurring_ok)) { - calendar_db_update_event($title,$desc,$begin,$end,$time_to_use,$recur,$repeats,$current_user->ID,$category,$linky,$_REQUEST['event_id']);+ calendar_db_update_event($title,$desc,$begin,$end,$time_to_use,$recur,$repeats,$current_user->ID,$category,$linky,sanitize_text_field(wp_unslash($_REQUEST['event_id']))); $result = calendar_db_get_event_id_by_insert_data($title,$desc,$begin,$end,$time_to_use,$recur,$repeats,$current_user->ID,$category,$linky); if ( empty($result) || empty($result[0]->event_id) )@@ -1182,7 +1182,7 @@ } else {- do_action('add_calendar_entry', 'edit');+ do_action('calendar_add_entry', 'edit'); ?> <div class="updated"><p><?php esc_html_e('Event updated successfully','calendar'); ?></p></div> <?php@@ -1192,15 +1192,15 @@ { // The form is going to be rejected due to field validation issues, so we preserve the users entries here $users_entires = new stdClass();- $users_entries->event_title = $title;- $users_entries->event_desc = $desc;- $users_entries->event_begin = $begin;- $users_entries->event_end = $end;- $users_entries->event_time = $time;- $users_entries->event_recur = $recur;- $users_entries->event_repeats = $repeats;- $users_entries->event_category = $category;- $users_entries->event_link = $linky;+ $calendar_users_entries->event_title = $title;+ $calendar_users_entries->event_desc = $desc;+ $calendar_users_entries->event_begin = $begin;+ $calendar_users_entries->event_end = $end;+ $calendar_users_entries->event_time = $time;+ $calendar_users_entries->event_recur = $recur;+ $calendar_users_entries->event_repeats = $repeats;+ $calendar_users_entries->event_category = $category;+ $calendar_users_entries->event_link = $linky; $error_with_saving = 1; } }@@ -1214,19 +1214,19 @@ <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("You can't delete an event if you haven't submitted an event id",'calendar'); ?></p></div> <?php }- elseif (wp_verify_nonce($_GET['_wpnonce'],'calendar-delete_'.$_REQUEST['event_id']) == false) {+ elseif (!isset($_GET['_wpnonce']) || wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])),'calendar-delete_'.sanitize_text_field(wp_unslash($_REQUEST['event_id']))) == false) { ?> <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("Security check failure, try deleting the event again",'calendar'); ?></p></div> <?php } else {- calendar_db_delete_event_by_id($_REQUEST['event_id']);- $result = calendar_db_get_event_id_by_id($_REQUEST['event_id']);+ calendar_db_delete_event_by_id(sanitize_text_field(wp_unslash($_REQUEST['event_id'])));+ $result = calendar_db_get_event_id_by_id(sanitize_text_field(wp_unslash($_REQUEST['event_id']))); if ( empty($result) || empty($result[0]->event_id) ) {- do_action('add_calendar_entry', 'delete');+ do_action('calendar_add_entry', 'delete'); ?> <div class="updated"><p><?php esc_html_e('Event deleted successfully','calendar'); ?></p></div> <?php@@ -1258,7 +1258,7 @@ } else {- calendar_events_edit_form('edit_save', $_REQUEST['event_id']);+ calendar_events_edit_form('edit_save', sanitize_text_field(wp_unslash($_REQUEST['event_id']))); } } else@@ -1281,9 +1281,9 @@ // Display the admin configuration page function calendar_config_edit() {- global $initial_style;+ global $calendar_initial_style; - if (isset($_POST['permissions']) && isset($_POST['style']) && wp_verify_nonce($_POST['_wpnonce'],'calendar-config') == false) {+ if (isset($_POST['permissions']) && isset($_POST['style']) && (!isset($_POST['_wpnonce']) || wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])),'calendar-config') == false)) { ?> <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("Security check failure, try editing the config again",'calendar'); ?></p></div> <?php@@ -1298,10 +1298,10 @@ else { $new_perms = 'manage_options'; } // We want to sanitize this but the inbuilt function clatters two valid CSS charaters, re-instate them!- $calendar_style = str_replace("\'","'",str_replace(">",">",wp_filter_nohtml_kses($_POST['style'])));- $display_upcoming_days = $_POST['display_upcoming_days'];+ $calendar_style = str_replace("\'","'",str_replace(">",">",wp_filter_nohtml_kses(wp_kses_post(wp_unslash($_POST['style'])))));+ $display_upcoming_days = isset($_POST['display_upcoming_days']) ? sanitize_text_field(wp_unslash($_POST['display_upcoming_days'])) : 7; - if ($_POST['display_author'] == 'on')+ if (isset($_POST['display_author']) && $_POST['display_author'] == 'on') { $disp_author = 'true'; }@@ -1310,7 +1310,7 @@ $disp_author = 'false'; } - if ($_POST['display_jump'] == 'on')+ if (isset($_POST['display_jump']) && $_POST['display_jump'] == 'on') { $disp_jump = 'true'; }@@ -1319,7 +1319,7 @@ $disp_jump = 'false'; } - if ($_POST['display_todays'] == 'on')+ if (isset($_POST['display_todays']) && $_POST['display_todays'] == 'on') { $disp_todays = 'true'; }@@ -1328,7 +1328,7 @@ $disp_todays = 'false'; } - if ($_POST['display_upcoming'] == 'on')+ if (isset($_POST['display_upcoming']) && $_POST['display_upcoming'] == 'on') { $disp_upcoming = 'true'; }@@ -1337,7 +1337,7 @@ $disp_upcoming = 'false'; } - if ($_POST['enable_categories'] == 'on')+ if (isset($_POST['enable_categories']) && $_POST['enable_categories'] == 'on') { $enable_categories = 'true'; }@@ -1346,7 +1346,7 @@ $enable_categories = 'false'; } - if ($_POST['enable_feed'] == 'on')+ if (isset($_POST['enable_feed']) && $_POST['enable_feed'] == 'on') { $enable_feed = 'true'; }@@ -1355,13 +1355,13 @@ $enable_feed = 'false'; } - if ($_POST['enhance_contrast'] == 'on') {+ if (isset($_POST['enhance_contrast']) && $_POST['enhance_contrast'] == 'on') { $enhance_contrast = 'true'; } else { $enhance_contrast = 'false'; } - if ($_POST['show_attribution_link'] == 'on') {+ if (isset($_POST['show_attribution_link']) && $_POST['show_attribution_link'] == 'on') { $show_attribution_link = 'true'; } else { $show_attribution_link = 'false';@@ -1389,7 +1389,7 @@ // Check to see if we are replacing the original style if (isset($_POST['reset_styles'])) { if ($_POST['reset_styles'] == 'on') {- calendar_update_config_value('calendar_style',$initial_style);+ calendar_update_config_value('calendar_style',$calendar_initial_style); } } @@ -1582,31 +1582,33 @@ // We do some checking to see what we're doing if (isset($_POST['mode']) && $_POST['mode'] == 'add') {- if (wp_verify_nonce($_POST['_wpnonce'],'calendar-category_add') == false) {+ if (!isset($_POST['_wpnonce']) || wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])),'calendar-category_add') == false) { ?> <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("Security check failure, try adding the category again",'calendar'); ?></p></div> <?php } else { // Proceed with the save- calendar_db_insert_category(stripslashes($_POST['category_name']), $_POST['category_colour']);+ $category_name = isset($_POST['category_name']) ? sanitize_text_field(wp_unslash($_POST['category_name'])) : '';+ $category_colour = isset($_POST['category_colour']) ? sanitize_text_field(wp_unslash($_POST['category_colour'])) : '';+ calendar_db_insert_category($category_name, $category_colour); echo "<div class=\"updated\"><p><strong>".esc_html__('Category added successfully','calendar')."</strong></p></div>"; } } else if (isset($_GET['mode']) && isset($_GET['category_id']) && $_GET['mode'] == 'delete') {- if (wp_verify_nonce($_GET['_wpnonce'],'calendar-category_delete_'.$_GET['category_id']) == false) {+ if (!isset($_GET['_wpnonce']) || wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])),'calendar-category_delete_'.sanitize_text_field(wp_unslash($_GET['category_id']))) == false) { ?> <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("Security check failure, try deleting the category again",'calendar'); ?></p></div> <?php } else {- calendar_db_delete_category($_GET['category_id']);- calendar_db_reset_event_categories_to_default_from_id($_GET['category_id']);+ calendar_db_delete_category(sanitize_text_field(wp_unslash($_GET['category_id'])));+ calendar_db_reset_event_categories_to_default_from_id(sanitize_text_field(wp_unslash($_GET['category_id']))); echo "<div class=\"updated\"><p><strong>".esc_html__('Category deleted successfully','calendar')."</strong></p></div>"; } } else if (isset($_GET['mode']) && isset($_GET['category_id']) && $_GET['mode'] == 'edit' && !isset($_POST['mode'])) {- $cur_cat = calendar_db_get_category_row_by_id($_GET['category_id']);+ $cur_cat = calendar_db_get_category_row_by_id(sanitize_text_field(wp_unslash($_GET['category_id']))); ?> <div class="wrap"> <h2><?php esc_html_e('Edit Category','calendar'); ?></h2>@@ -1636,13 +1638,16 @@ } else if (isset($_POST['mode']) && isset($_POST['category_id']) && isset($_POST['category_name']) && isset($_POST['category_colour']) && $_POST['mode'] == 'edit') {- if (wp_verify_nonce($_POST['_wpnonce'],'calendar-category_edit_'.$_POST['category_id']) == false) {+ if (!isset($_POST['_wpnonce']) || wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])),'calendar-category_edit_'.sanitize_text_field(wp_unslash($_POST['category_id']))) == false) { ?> <div class="error"><p><strong><?php esc_html_e('Error','calendar'); ?>:</strong> <?php esc_html_e("Security check failure, try editing the category again",'calendar'); ?></p></div> <?php } else {- // Proceed with the save- calendar_db_update_category(stripslashes($_POST['category_name']), $_POST['category_colour'], $_POST['category_id']);+ // Proceed with the save+ $category_name = isset($_POST['category_name']) ? sanitize_text_field(wp_unslash($_POST['category_name'])) : '';+ $category_colour = isset($_POST['category_colour']) ? sanitize_text_field(wp_unslash($_POST['category_colour'])) : '';+ $category_id = isset($_POST['category_id']) ? sanitize_text_field(wp_unslash($_POST['category_id'])) : 0;+ calendar_db_update_category($category_name, $category_colour, $category_id); echo "<div class=\"updated\"><p><strong>".esc_html__('Category edited successfully','calendar')."</strong></p></div>"; } }@@ -1857,7 +1862,7 @@ while ($day_count < $future_days+1) { list($y,$m,$d) = explode("-",gmdate("Y-m-d",mktime($day_count*24,0,0,gmdate("m",calendar_ctwo()),gmdate("d",calendar_ctwo()),gmdate("Y",calendar_ctwo()))));- $events = grab_events($y,$m,$d,'upcoming',$cat_list);+ $events = calendar_grab_events($y,$m,$d,'upcoming',$cat_list); usort($events, "calendar_time_cmp"); if (count($events) != 0) { $output .= '<li>'.wp_date(get_option('date_format'),mktime($day_count*24,0,0,gmdate("m",calendar_ctwo()),gmdate("d",calendar_ctwo()),gmdate("Y",calendar_ctwo()))).'<ul>';@@ -1895,7 +1900,7 @@ if (calendar_get_config_value('display_todays') == 'true') { $output = '<ul>';- $events = grab_events(gmdate("Y",calendar_ctwo()),gmdate("m",calendar_ctwo()),gmdate("d",calendar_ctwo()),'todays',$cat_list);+ $events = calendar_grab_events(gmdate("Y",calendar_ctwo()),gmdate("m",calendar_ctwo()),gmdate("d",calendar_ctwo()),'todays',$cat_list); usort($events, "calendar_time_cmp"); foreach($events as $event) {@@ -1934,7 +1939,7 @@ foreach($events as $event) { $output .= '<span class="calendar_bullet" style="position:relative;display:inline;width:unset;background:none;">* </span>'.calendar_draw_event($event).'<br />';- $output = apply_filters('modify_drawn_event_content', $output, $event);+ $output = apply_filters('calendar_modify_drawn_event_content', $output, $event); } return $output; }@@ -2087,7 +2092,7 @@ } // A function that determines an appropriate foreground colour from the background-function getContrastYIQ($hexcolor){+function calendar_getContrastYIQ($hexcolor){ if (preg_match('/#([a-fA-F0-9]{3}){1,2}\b/',$hexcolor)) { if (strlen($hexcolor)==4) { $r = hexdec(str_repeat(substr($hexcolor,1,1),2));@@ -2123,7 +2128,7 @@ { $cat_details = calendar_db_get_category_row_by_id($event->event_category); if ($contrast == 'true') {- $fgcolor=getContrastYIQ($cat_details->category_colour);+ $fgcolor=calendar_getContrastYIQ($cat_details->category_colour); $style = 'style="background-color:'.$cat_details->category_colour.'; color:'.$fgcolor.';"'; } else { $style = 'style="background-color:'.$cat_details->category_colour.';"';@@ -2149,15 +2154,15 @@ if ($event->event_link != '') { $linky = $event->event_link; } else { $linky = '#'; } - $linky = apply_filters('modify_calendar_link', $linky, $event);+ $linky = apply_filters('calendar_modify_link', $linky, $event); - $details = '<span class="calnk"><a href="'.$linky.'" '.$style.'>' . $event->event_title . '<span '.$style.'>' . $header_details . '' . $event->event_desc . '</span></a></span>';+ $details = '<span class="calnk"><a href="'.$linky.'" '.$style.'>' . $event->event_title . '<span '.$style.'>' . $header_details . '' . wp_kses_post($event->event_desc) . '</span></a></span>'; return $details; } // Grab all events for the requested date from calendar-function grab_events($y,$m,$d,$typing,$cat_list = '')+function calendar_grab_events($y,$m,$d,$typing,$cat_list = '') { global $wpdb; @@ -2458,12 +2463,15 @@ $date_switcher = calendar_get_config_value('display_jump'); if ($date_switcher == 'true') {+ $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : ''; $calendar_body .= '<tr> <td colspan="7" class="calendar-date-switcher">- <form method="get" action="'.htmlspecialchars($_SERVER['REQUEST_URI']).'">+ <form method="get" action="'.$request_uri.'"> '; $qsa = array();- parse_str($_SERVER['QUERY_STRING'],$qsa);+ if (isset($_SERVER['QUERY_STRING'])) {+ parse_str(sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])),$qsa);+ } foreach ($qsa as $name => $argument) { if ($name != 'calendar_month' && $name != 'calendar_yr' && preg_match("/^[A-Za-z0-9\-\_]+$/",$name) && preg_match("/^[A-Za-z0-9\-\_]+$/",$argument))@@ -2583,7 +2591,7 @@ if (get_option('start_of_week') == 0) { // This bit of code is for styles believe it or not.- $grabbed_events = grab_events($c_year,$c_month,$i,'calendar',$cat_list);+ $grabbed_events = calendar_grab_events($c_year,$c_month,$i,'calendar',$cat_list); $no_events_class = ''; if (!count($grabbed_events)) {@@ -2594,7 +2602,7 @@ } else {- $grabbed_events = grab_events($c_year,$c_month,$i,'calendar',$cat_list);+ $grabbed_events = calendar_grab_events($c_year,$c_month,$i,'calendar',$cat_list); $no_events_class = ''; if (!count($grabbed_events)) {@@ -2668,7 +2676,7 @@ $firstevent = array_shift($arr_values); $cat_details = calendar_db_get_category_row_by_id($firstevent->event_category); if ($contrast == 'true') {- $fgcolor = getContrastYIQ($cat_details->category_colour);+ $fgcolor = calendar_getContrastYIQ($cat_details->category_colour); $style = 'style="background-color:' . $cat_details->category_colour . '; color:' . $fgcolor . '"'; } else { $style = 'style="background-color:' . $cat_details->category_colour . ';"';@@ -2713,8 +2721,7 @@ } // Carry on with the script - $name_months = array(1=>__('January','calendar'),__('February','calendar'),__('March','calendar'),__('April','calendar'),__('May','calendar'),__('June','calendar'),__('July','\-calendar'),__('August','calendar'),__('September','calendar'),__('October','calendar'),__('November','calendar'),__('December','calendar'));+ $name_months = array(1=>__('January','calendar'),__('February','calendar'),__('March','calendar'),__('April','calendar'),__('May','calendar'),__('June','calendar'),__('July','calendar'),__('August','calendar'),__('September','calendar'),__('October','calendar'),__('November','calendar'),__('December','calendar')); // If we don't pass arguments we want a calendar that is relevant to today if (empty($get_month) || empty($get_year))@@ -2845,7 +2852,7 @@ if (get_option('start_of_week') == 0) { // This bit of code is for styles believe it or not.- $grabbed_events = grab_events($c_year,$c_month,$i,'calendar',$cat_list);+ $grabbed_events = calendar_grab_events($c_year,$c_month,$i,'calendar',$cat_list); $no_events_class = ''; if (!count($grabbed_events)) {@@ -2856,7 +2863,7 @@ } else {- $grabbed_events = grab_events($c_year,$c_month,$i,'calendar',$cat_list);+ $grabbed_events = calendar_grab_events($c_year,$c_month,$i,'calendar',$cat_list); $no_events_class = ''; if (!count($grabbed_events)) {
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - CWE-79 - calendar.php - Lines 901-908, 1048-1055
Old Code:
```php
$title = !empty($_REQUEST['event_title']) ? stripslashes($_REQUEST['event_title']) : '';
$desc = !empty($_REQUEST['event_desc']) ? stripslashes($_REQUEST['event_desc']) : '';
$begin = !empty($_REQUEST['event_begin']) ? $_REQUEST['event_begin'] : '';
$end = !empty($_REQUEST['event_end']) ? $_REQUEST['event_end'] : '';
$time = !empty($_REQUEST['event_time']) ? $_REQUEST['event_time'] : '';
$recur = !empty($_REQUEST['event_recur']) ? $_REQUEST['event_recur'] : '';
$repeats = !empty($_REQUEST['event_repeats']) ? $_REQUEST['event_repeats'] : '';
$category = !empty($_REQUEST['event_category']) ? $_REQUEST['event_category'] : '';
$linky = !empty($_REQUEST['event_link']) ? $_REQUEST['event_link'] : '';
```
Fixed Code:
```php
$title = !empty($_REQUEST['event_title']) ? wp_kses_post(wp_unslash($_REQUEST['event_title'])) : '';
$desc = !empty($_REQUEST['event_desc']) ? wp_kses_post(wp_unslash($_REQUEST['event_desc'])) : '';
$begin = !empty($_REQUEST['event_begin']) ? wp_kses_post(wp_unslash($_REQUEST['event_begin'])) : '';
$end = !empty($_REQUEST['event_end']) ? wp_kses_post(wp_unslash($_REQUEST['event_end'])) : '';
$time = !empty($_REQUEST['event_time']) ? wp_kses_post(wp_unslash($_REQUEST['event_time'])) : '';
$recur = !empty($_REQUEST['event_recur']) ? wp_kses_post(wp_unslash($_REQUEST['event_recur'])) : '';
$repeats = !empty($_REQUEST['event_repeats']) ? wp_kses_post(wp_unslash($_REQUEST['event_repeats'])) : '';
$category = !empty($_REQUEST['event_category']) ? wp_kses_post(wp_unslash($_REQUEST['event_category'])) : '';
$linky = !empty($_REQUEST['event_link']) ? wp_kses_post(wp_unslash($_REQUEST['event_link'])) : '';
```
Explanation:
The old code used `stripslashes()` which only removes escape characters but provides no protection against XSS attacks. User input from `$_REQUEST` was directly used without sanitization. The fix replaces this with `wp_kses_post()` which sanitizes HTML/PHP tags and `wp_unslash()` to remove slashes, providing proper XSS protection for WordPress.
---
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Request Forgery (CSRF) - CWE-352 - calendar.php - Lines 892, 1063, 1217, 1585, 1598, 1641
Old Code:
```php
if (wp_verify_nonce($_POST['_wpnonce'],'calendar-add') == false) {
```
Fixed Code:
```php
if (!isset($_POST['_wpnonce']) || wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])),'calendar-add') == false) {
```
Explanation:
The old code did not check if the nonce was set before attempting to verify it, which could cause a fatal error. More critically, the nonce token was not sanitized before verification. The fix adds proper isset() checks and sanitizes the nonce with `sanitize_text_field(wp_unslash())` before verification, preventing CSRF attacks and handling missing nonce tokens gracefully.
---
Vulnerability Existed: yes
FALSE POSITIVE
Improper Input Validation - CWE-20 - calendar.php - Lines 1301, 1304
Old Code:
```php
$calendar_style = str_replace("\'","'",str_replace(">",">",wp_filter_nohtml_kses($_POST['style'])));
$display_upcoming_days = $_POST['display_upcoming_days'];
```
Fixed Code:
```php
$calendar_style = str_replace("\'","'",str_replace(">",">",wp_filter_nohtml_kses(wp_kses_post(wp_unslash($_POST['style'])))));
$display_upcoming_days = isset($_POST['display_upcoming_days']) ? sanitize_text_field(wp_unslash($_POST['display_upcoming_days'])) : 7;
```
Explanation:
The old code did not sanitize `$_POST['style']` before processing and directly used `$_POST['display_upcoming_days']` without validation or isset() check. The fix adds `wp_kses_post(wp_unslash())` for proper sanitization, checks for isset() before accessing the variable, and provides a sensible default value (7).
---
Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Special Elements used in an SQL Command - CWE-89 - calendar.php - Lines 1019, 1171, 1174, 1224, 1227, 1261
Old Code:
```php
do_action('add_calendar_entry', 'add');
calendar_db_update_event($title,$desc,$begin,$end,$time_to_use,$recur,$repeats,$current_user->ID,$category,$linky,$_REQUEST['event_id']);
calendar_db_delete_event_by_id($_REQUEST['event_id']);
```
Fixed Code:
```php
do_action('calendar_add_entry', 'add');
calendar_db_update_event($title,$desc,$begin,$end,$time_to_use,$recur,$repeats,$current_user->ID,$category,$linky,sanitize_text_field(wp_unslash($_REQUEST['event_id'])));
calendar_db_delete_event_by_id(sanitize_text_field(wp_unslash($_REQUEST['event_id'])));
```
Explanation:
The old code passed unsanitized `$_REQUEST['event_id']` directly to database functions, which could allow SQL injection attacks. The fix sanitizes the event_id with `sanitize_text_field(wp_unslash())` before passing it to database operations, preventing SQL injection. Additionally, the action hook was renamed from a generic name to a more descriptive namespaced name to avoid conflicts.
---
Vulnerability Existed: yes
TRUE POSITIVE
Improper Input Validation - CWE-20 - calendar.php - Lines 1596-1610, 1591
Old Code:
```php
calendar_db_insert_category(stripslashes($_POST['category_name']), $_POST['category_colour']);
calendar_db_delete_category($_GET['category_id']);
calendar_db_get_category_row_by_id($_GET['category_id']);
```
Fixed Code:
```php
$category_name = isset($_POST['category_name']) ? sanitize_text_field(wp_unslash($_POST['category_name'])) : '';
$category_colour = isset($_POST['category_colour']) ? sanitize_text_field(wp_unslash($_POST['category_colour'])) : '';
calendar_db_insert_category($category_name, $category_colour);
calendar_db_delete_category(sanitize_text_field(wp_unslash($_GET['category_id'])));
calendar_db_get_category_row_by_id(sanitize_text_field(wp_unslash($_GET['category_id'])));
```
Explanation:
The old code used `stripslashes()` and passed unsanitized GET/POST parameters directly to database functions. The fix replaces `stripslashes()` with `wp_unslash()` combined with `sanitize_text_field()` and adds isset() checks, preventing SQL injection and improper data handling.
---
Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - CWE-79 - calendar.php - Lines 2154, 2464-2466
Old Code:
```php
$details = '<span class="calnk"><a href="'.$linky.'" '.$style.'>' . $event->event_title . '<span '.$style.'>' . $header_details . '' . $event->event_desc . '</span></a></span>';
$calendar_body .= '<tr>
<td colspan="7" class="calendar-date-switcher">
<form method="get" action="'.htmlspecialchars($_SERVER['REQUEST_URI']).'">
';
```
Fixed Code:
```php
$details = '<span class="calnk"><a href="'.$linky.'" '.$style.'>' . $event->event_title . '<span '.$style.'>' . $header_details . '' . wp_kses_post($event->event_desc) . '</span></a></span>';
$request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
$calendar_body .= '<tr>
<td colspan="7" class="calendar-date-switcher">
<form method="get" action="'.$request_uri.'">
';
```
Explanation:
The old code output `$event->event_desc` without sanitization and used `htmlspecialchars()` on `$_SERVER['REQUEST_URI']` which is insufficient protection. The fix applies `wp_kses_post()` to sanitize event description and sanitizes the REQUEST_URI with `sanitize_text_field(wp_unslash())`, adding isset() check for safety.
---
Vulnerability Existed: yes
TRUE POSITIVE
Improper Input Validation - CWE-20 - calendar.php - Lines 2466-2468
Old Code:
```php
$qsa = array();
parse_str($_SERVER['QUERY_STRING'],$qsa);
```
Fixed Code:
```php
$qsa = array();
if (isset($_SERVER['QUERY_STRING'])) {
parse_str(sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])),$qsa);
}
```
Explanation:
The old code did not check if QUERY_STRING was set before using it and did not sanitize it before parsing, potentially causing notices or vulnerabilities. The fix adds isset() check and sanitizes with `sanitize_text_field(wp_unslash())` before parsing.
CVE Analysis Results:
CVE-2025-14548: Yes
View CVE Description
The Calendar plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'event_desc' parameter in all versions up to, and including, 1.3.16 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page, granted they can convince an administrator to enable lower privilege users to manage calendar events via the plugin settings.
Showing 1 to 1 of 1 results