Analysis Report Folder Analysis cache/church-admin_5.0.28 → cache/church-admin_5.0.29 - CVE-2026-0682

Shared security patch analysis results

AI Used: claude_cli haiku
Share this analysis
CVE Security Analysis & Writeups

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-2026-0682
AI-Generated Analysis
Use quotes for exact: \"SQL injection\" | Operators: hello AND bye, admin OR root, -error, NOT warning
Showing 0 to 0 of 0 results
church-admin.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/church-admin.php	2026-01-18 00:19:18.079680436 +0000+++ cache/church-admin_5.0.29/church-admin.php	2026-01-18 00:24:12.189950085 +0000@@ -4,7 +4,7 @@ Plugin Name: Church Admin Plugin URI: http://www.churchadminplugin.com/ Description: Manage church life with address book, schedule, classes, small groups, and advanced communication tools - bulk email and sms. -Version: 5.0.28+Version: 5.0.29 Tags: sermons, sermons, prayer, membership, SMS, Bible, events, calendar, email, small groups, contact form, giving, administration, management, child protection, safeguarding Author: Andy Moyle Text Domain: church-admin@@ -50,7 +50,7 @@   */-if(!defined('CHURCH_ADMIN_VERSION')){define('CHURCH_ADMIN_VERSION','5.0.28');}+if(!defined('CHURCH_ADMIN_VERSION')){define('CHURCH_ADMIN_VERSION','5.0.29');}  define('CA_PAYPAL',"https://www.paypal.com/cgi-bin/webscr"); require_once( plugin_dir_path( __FILE__ ) .'includes/functions.php');@@ -1449,7 +1449,9 @@             break; 			case'get_people':church_admin_ajax_people(TRUE);break; 			case'people':case'edit_funnel':case'delete_funnel':church_admin_sortable_script();break;-            case 'upload-mp3':church_admin_date_picker_script();church_admin_autocomplete_script();break;+            case 'upload-mp3':+                church_admin_date_picker_script();church_admin_autocomplete_script();+            break;        		} 	}
AI Analysis
```
Vulnerability Existed: no
[No Vulnerability] - [N/A] - church-admin.php [All lines]

Old Code:
Version: 5.0.28
if(!defined('CHURCH_ADMIN_VERSION')){define('CHURCH_ADMIN_VERSION','5.0.28');}
case 'upload-mp3':church_admin_date_picker_script();church_admin_autocomplete_script();break;

Fixed Code:
Version: 5.0.29
if(!defined('CHURCH_ADMIN_VERSION')){define('CHURCH_ADMIN_VERSION','5.0.29');}
case 'upload-mp3':
    church_admin_date_picker_script();church_admin_autocomplete_script();
break;

Explanation:
This diff contains only non-security changes: (1) A version bump from 5.0.28 to 5.0.29, (2) Code formatting/readability improvement by breaking a long line into multiple lines for the 'upload-mp3' case statement. No security vulnerabilities are introduced or fixed. The changes do not affect input validation, output encoding, authentication, authorization, or any other security-relevant functionality. This is a routine maintenance update with cosmetic code formatting.
```
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
gutenberg/php-blocks.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/gutenberg/php-blocks.php	2026-01-18 00:19:18.087680932 +0000+++ cache/church-admin_5.0.29/gutenberg/php-blocks.php	2026-01-18 00:24:12.205951079 +0000@@ -169,7 +169,7 @@ 	/************************** 	 * Add data for dropdowns 	 **************************/-	$seriesArray=array(array('value'=>null,'label'=>esc_html( __('All series')) ));+	$seriesArray=array(array('value'=>null,'label'=>esc_html( __('All series','church-admin')) )); 	$series = $wpdb->get_results('SELECT * FROM '.$wpdb->prefix.'church_admin_sermon_series ORDER BY series_name ASC'); 	 @@ -519,6 +519,7 @@     $out.='<div class="'.esc_attr($container).'"><div style="position:relative;padding-top:56.25%"><iframe class="ca-video" style="position:absolute;top:0;left:0;width:100%;height:100%;" src="'.esc_url($embed['embed']).'" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div></div>';     $views=church_admin_youtube_views_api( esc_attr($embed['id']) );     if(!empty( $views)&& !empty( $attribute['show_views'] ) ){+		/* translators: %s: Number of views */ 		$out.='<p>'.esc_html( sprintf(__('%1$s views','church-admin' ) ,$views) ).'</p>'; 	}     $out.='</div>';
AI Analysis
Vulnerability Existed: no
Translation String Missing Domain Parameter - No CWE (Internationalization Best Practice) - gutenberg/php-blocks.php - Line 172
Old Code:
```
$seriesArray=array(array('value'=>null,'label'=>esc_html( __('All series')) ));
```
Fixed Code:
```
$seriesArray=array(array('value'=>null,'label'=>esc_html( __('All series','church-admin')) ));
```
Explanation:
This is not a security vulnerability but an internationalization (i18n) best practice fix. The `__()` function was missing the text domain parameter ('church-admin'). While this doesn't introduce a security flaw, it can cause translation issues. The fix ensures strings are properly registered with the correct domain for WordPress translation systems. No security issue existed in the original code.

---

Vulnerability Existed: no
Missing Translator Comment - No CWE (Code Quality) - gutenberg/php-blocks.php - Line 522
Old Code:
```
$out.='<p>'.esc_html( sprintf(__('%1$s views','church-admin' ) ,$views) ).'</p>';
```
Fixed Code:
```
/* translators: %s: Number of views */
$out.='<p>'.esc_html( sprintf(__('%1$s views','church-admin' ) ,$views) ).'</p>';
```
Explanation:
This is a code quality improvement, not a security fix. The addition of a translator comment (`/* translators: ... */`) provides context for translators about the placeholder variable. This helps ensure accurate translations but does not address any security vulnerability. The code was already properly escaped with `esc_html()` and had the correct text domain parameter.

---

**Summary:** No security vulnerabilities were found in this diff. Both changes are improvements to internationalization and code documentation practices.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/custom_fields.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/custom_fields.php	2026-01-18 00:19:18.091681181 +0000+++ cache/church-admin_5.0.29/includes/custom_fields.php	2026-01-18 00:24:12.233952817 +0000@@ -16,16 +16,16 @@  	global $wpdb; 	//$wpdb->show_errors;-    $out='<h2>'.esc_html( __('Custom fields','church-admin' ) ).'</h2>';+    echo'<h2>'.esc_html( __('Custom fields','church-admin' ) ).'</h2>'; 	-	$out.='<p><a class="button-primary" href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit-custom-field&amp;section=people','edit-custom-field').'">'.esc_html( __('Add a custom field','church-admin' ) ).'</a></p>';+	echo '<p><a class="button-primary" href="'.esc_url(wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit-custom-field&amp;section=people','edit-custom-field')).'">'.esc_html( __('Add a custom field','church-admin' ) ).'</a></p>'; 	$custom_fields=$wpdb->get_results('SELECT * FROM '.$wpdb->prefix.'church_admin_custom_fields WHERE section="household" OR section="people" ORDER BY section,custom_order,name'); 	if(!empty( $custom_fields) ) 	{-		$out.=__('Drag and Drop to change row display order','church-admin');+		echo esc_html(__('Drag and Drop to change row display order','church-admin')); 		$thead='<tr><th class="column-primary">'.esc_html( __('Custom field name','church-admin' ) ).'</th><th>'.esc_html( __('Edit','church-admin' ) ).'</th><th>'.esc_html( __('Delete','church-admin' ) ).'</th><th>'.esc_html( __('Section','church-admin' ) ).'</th><th>'.esc_html( __('Custom field type','church-admin' ) ).'</th><th>'.esc_html( __('Default','church-admin' ) ).'</th><th>'.esc_html( __('First registration only','church-admin') ).'</th></tr>'; 		-		$out.='<table  id="sortable" class="widefat striped"><thead>'.$thead.'</thead><tbody class="content">';+		echo '<table  id="sortable" class="widefat striped"><thead>'.wp_kses_post($thead).'</thead><tbody class="content">'; 		 		foreach( $custom_fields AS $custom_field) 		{@@ -33,17 +33,17 @@ 			if(!empty( $custom_field->default_value) )  {$default=$custom_field->default_value;}else{$default="";} 			$edit='<a href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit-custom-field&amp;section=people&amp;id='.(int)$custom_field->ID,'edit-custom-field').'">'.esc_html( __('Edit','church-admin' ) ).'</a>'; 			$delete='<a href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=delete-custom-field&amp;section=people&amp;id='.(int)$custom_field->ID,'delete-custom-field').'">'.esc_html( __('Delete','church-admin' ) ).'</a>';-			$out.='<tr  class="sortable" id="'.(int)$custom_field->ID.'">';-			$out.='<td data-colname="'.esc_html( __('Custom field','church-admin' ) ).'" class="column-primary">'.esc_html( $custom_field->name).'</td>';-			$out.='<td data-colname="'.esc_html( __('Edit','church-admin' ) ).'">'.$edit.'</td>';-			$out.='<td data-colname="'.esc_html( __('Delete','church-admin' ) ).'">'.$delete.'</td>';+			echo '<tr  class="sortable" id="'.(int)$custom_field->ID.'">';+			echo '<td data-colname="'.esc_html( __('Custom field','church-admin' ) ).'" class="column-primary">'.esc_html( $custom_field->name).'</td>';+			echo '<td data-colname="'.esc_html( __('Edit','church-admin' ) ).'">'.$edit.'</td>';+			echo '<td data-colname="'.esc_html( __('Delete','church-admin' ) ).'">'.$delete.'</td>'; 			-			$out.='<td data-colname="'.esc_html( __('Custom field section','church-admin' ) ).'">'.esc_html( $custom_field->section).'</td>';-			$out.='<td data-colname="'.esc_html( __('Custom field type','church-admin' ) ).'">'.esc_html( $custom_field->type).'</td>';-			$out.='<td data-colname="'.esc_html( __('Default value','church-admin' ) ).'">'.esc_html( $default).'</td>';-			$out.='<td data-colname="'.esc_html( __('Onboarding only','church-admin' ) ).'">'.esc_html($onboarding).'</td></tr>';+			echo '<td data-colname="'.esc_html( __('Custom field section','church-admin' ) ).'">'.esc_html( $custom_field->section).'</td>';+			echo '<td data-colname="'.esc_html( __('Custom field type','church-admin' ) ).'">'.esc_html( $custom_field->type).'</td>';+			echo '<td data-colname="'.esc_html( __('Default value','church-admin' ) ).'">'.esc_html( $default).'</td>';+			echo '<td data-colname="'.esc_html( __('Onboarding only','church-admin' ) ).'">'.esc_html($onboarding).'</td></tr>'; 		}-		$out.='</tbody><tfoot>'.$thead.'</tfoot></table>';+		echo '</tbody><tfoot>'.wp_kses_post($thead).'</tfoot></table>'; 	} 	echo' <script type="text/javascript"> @@ -141,31 +141,33 @@ 					} 			} 		}- 		$out.='<div class="notice notice-success"><h2>'.esc_html( __('Custom field saved','church-admin' ) ).'</h2></div>';- 		$out.=church_admin_list_custom_fields();+ 		echo '<div class="notice notice-success"><h2>'.esc_html( __('Custom field saved','church-admin' ) ).'</h2></div>';+ 		church_admin_list_custom_fields();   	}  	else  	{- 		$out='<h2>'.esc_html( __('Edit custom field','church-admin' ) ).'</h2>';- 		$out.='<form action="" method="POST">';- 		$out.='<table class="form-table">';- 		$out.='<tr><th scope="row">'.esc_html( __('Custom field name','church-admin' ) ).'</th><td><input type="text" name="custom-field-name" ';- 		if(!empty( $data->name) )$out.=' value="'.esc_html( $data->name).'" ';- 		$out.='/>';+ 		echo'<h2>'.esc_html( __('Edit custom field','church-admin' ) ).'</h2>';+ 		echo'<form action="" method="POST">';+ 		echo'<table class="form-table">';+ 		echo'<tr><th scope="row">'.esc_html( __('Custom field name','church-admin' ) ).'</th><td><input type="text" name="custom-field-name" ';+ 		if(!empty( $data->name) ){+			echo' value="'.esc_html( $data->name).'" ';+		}+ 		echo '/>';  		//TYPE 		if ( empty( $data->section) )$data->section=''; 		if ( empty( $data->default_value) )$data->default_value='';  		if ( empty( $data->type) )$data->type='';- 		$out.='<tr><th scope="row">'.esc_html( __('Custom field type','church-admin' ) ).'</th><td><select name="custom-field-type" class="custom-type"><option value="boolean" '.selected('boolean',$data->type,FALSE).'>'.esc_html( __('Yes/No','church-admin' ) ).'</option><option value="date" '.selected('date',$data->type,FALSE).'>'.esc_html( __('Date','church-admin' ) ).'</option><option value="text" '.selected('text',$data->type,FALSE).'>'.esc_html( __('Text field','church-admin' ) ).'</option><option value="radio"'.selected('radio',$data->type,FALSE).'>'.esc_html( __('Radio buttons','church-admin' ) ).'</option>+ 		echo'<tr><th scope="row">'.esc_html( __('Custom field type','church-admin' ) ).'</th><td><select name="custom-field-type" class="custom-type"><option value="boolean" '.selected('boolean',$data->type,FALSE).'>'.esc_html( __('Yes/No','church-admin' ) ).'</option><option value="date" '.selected('date',$data->type,FALSE).'>'.esc_html( __('Date','church-admin' ) ).'</option><option value="text" '.selected('text',$data->type,FALSE).'>'.esc_html( __('Text field','church-admin' ) ).'</option><option value="radio"'.selected('radio',$data->type,FALSE).'>'.esc_html( __('Radio buttons','church-admin' ) ).'</option> 		 <option value="checkbox"'.selected('checkbox',$data->type,FALSE).'>'.esc_html( __('Checkboxes','church-admin' ) ).'</option> 		 <option value="select"'.selected('select',$data->type,FALSE).'>'.esc_html( __('Select dropdown','church-admin' ) ).'</option></select></td></tr>'; 		//SECTION-		if(!empty( $data) )$out.='<tr><th scope="row" colspan=2>'.esc_html( __('Changing from Household to People will require editing people entries for which person in a household the data applies to.','church-admin' ) ).'</th></tr>';-		$out.='<tr><th scope="row">'.esc_html( __('Custom field section','church-admin' ) ).'</th><td><select name="custom-field-section" class="custom-section"><option value="people" '.selected('people',$data->section,FALSE).'>'.esc_html( __('People','church-admin' ) ).'</option><option value="household" '.selected('household',$data->section,FALSE).'>'.esc_html( __('Household','church-admin' ) ).'</option>';-		/* $out.='<option value="event" '.selected('event',$data->section,FALSE).'>'.esc_html( __('Event ticket','church-admin' ) ).'</option>';+		if(!empty( $data) )echo'<tr><th scope="row" colspan=2>'.esc_html( __('Changing from Household to People will require editing people entries for which person in a household the data applies to.','church-admin' ) ).'</th></tr>';+		echo'<tr><th scope="row">'.esc_html( __('Custom field section','church-admin' ) ).'</th><td><select name="custom-field-section" class="custom-section"><option value="people" '.selected('people',$data->section,FALSE).'>'.esc_html( __('People','church-admin' ) ).'</option><option value="household" '.selected('household',$data->section,FALSE).'>'.esc_html( __('Household','church-admin' ) ).'</option>';+		/* echo '<option value="event" '.selected('event',$data->section,FALSE).'>'.esc_html( __('Event ticket','church-admin' ) ).'</option>'; 		*/-		$out.='</select></td></tr>';+		echo'</select></td></tr>'; 		if(!empty( $data->type) ) 		{ 			$option= !empty($data->options) ? maybe_unserialize($data->options):null;@@ -204,26 +206,26 @@ 				break; 			} 			-			$out.='<tr class="boolean" '.$boolean.'><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th>';-			$out.='<td><select name="custom-field-default" '.$booleanField.' class="boolean-default"><option value="1" ';-			if(!empty( $data->default_value) )$out.=' selected="selected" ';-			$out.='>'.esc_html( __('Yes','church-admin' ) ).'</option><option value="0" ';-			if(isset( $data->default_value)&& $data->default_value=="0")$out.=' selected="selected" ';-			$out.='>'.esc_html( __('No','church-admin' ) ).'</option></select></td></tr>';--			$out.='<tr class="text" '.$text.'><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th>';-			$out.='<td ><input type="text" class="text-default" '.$textField.' name="custom-field-default" ';-			if(!empty( $data->default_value) )$out.=' value="'.esc_html( $data->default_value).'" ';-			$out.='/></td></tr>';+			echo'<tr class="boolean" '.$boolean.'><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th>';+			echo'<td><select name="custom-field-default" '.$booleanField.' class="boolean-default"><option value="1" ';+			if(!empty( $data->default_value) )echo' selected="selected" ';+			echo'>'.esc_html( __('Yes','church-admin' ) ).'</option><option value="0" ';+			if(isset( $data->default_value)&& $data->default_value=="0")echo' selected="selected" ';+			echo'>'.esc_html( __('No','church-admin' ) ).'</option></select></td></tr>';++			echo'<tr class="text" '.$text.'><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th>';+			echo'<td ><input type="text" class="text-default" '.$textField.' name="custom-field-default" ';+			if(!empty( $data->default_value) )echo' value="'.esc_html( $data->default_value).'" ';+			echo'/></td></tr>'; 			//options-			$out.='<tr class="options" '.$options.'><th scope="row">'.esc_html( __('Add upto 20 choices','church-admin' ) ).'</th><td>';+			echo'<tr class="options" '.$options.'><th scope="row">'.esc_html( __('Add upto 20 choices','church-admin' ) ).'</th><td>'; 			$options_chosen = !empty($data->options)? unserialize($data->options) : array(); 			for($x=0;$x<=20;$x++){-				$out.='<input type="text" name="options[]" ';-				if(!empty($option[$x]))$out.=' value="'.esc_html( $option[$x]).'" ';-				$out.='><br/>';+				echo'<input type="text" name="options[]" ';+				if(!empty($option[$x]))echo' value="'.esc_html( $option[$x]).'" ';+				echo'><br/>'; 			}-			$out.='</td></tr>';+			echo'</td></tr>'; 			  @@ -231,39 +233,39 @@ 			 		} 		else {-			$out.='<tr class="boolean" style="display:table-row"><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th><td><select  class="boolean-default" name="custom-field-default"><option value="1" ';-			if(!empty( $data->default_value) )$out.=' selected="selected" ';-			$out.='>'.esc_html( __('Yes','church-admin' ) ).'</option><option value="0" ';-			if(isset( $data->default_value)&& $data->default_value=="0")$out.=' selected="selected" ';-			$out.='>'.esc_html( __('No','church-admin' ) ).'</option></select></td></tr>';--			$out.='<tr class="text"  style="display:none"><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th><td><input disabled="disabled" type="text" class="text-default" name="custom-field-default" ';-			if(!empty( $data->default_value) )$out.=' value="'.esc_html( $data->default_value).'" ';-			$out.='/></td></tr>';+			echo'<tr class="boolean" style="display:table-row"><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th><td><select  class="boolean-default" name="custom-field-default"><option value="1" ';+			if(!empty( $data->default_value) )echo' selected="selected" ';+			echo'>'.esc_html( __('Yes','church-admin' ) ).'</option><option value="0" ';+			if(isset( $data->default_value)&& $data->default_value=="0")echo' selected="selected" ';+			echo'>'.esc_html( __('No','church-admin' ) ).'</option></select></td></tr>';++			echo'<tr class="text"  style="display:none"><th scope="row">'.esc_html( __('Default','church-admin' ) ).'</th><td><input disabled="disabled" type="text" class="text-default" name="custom-field-default" ';+			if(!empty( $data->default_value) )echo' value="'.esc_html( $data->default_value).'" ';+			echo'/></td></tr>'; 			//options-			$out.='<tr class="options" style="display:none"><th scope="row">'.esc_html( __('Add up to 20 choices','church-admin' ) ).'</th><td>';+			echo'<tr class="options" style="display:none"><th scope="row">'.esc_html( __('Add up to 20 choices','church-admin' ) ).'</th><td>'; 			$options_chosen = !empty($data->options)? unserialize($data->options) : array(); 			for($x=0;$x<20;$x++){ 				$y=$x+1;-				$out.='<p>'.$y.' <input type="text" name="options[]" ';-				if(!empty($option[$x]))$out.=' value="'.esc_html( $option[$x]).'" ';-				$out.='></p>';+				echo'<p>'.$y.' <input type="text" name="options[]" ';+				if(!empty($option[$x]))echo' value="'.esc_html( $option[$x]).'" ';+				echo'></p>'; 			}-			$out.='</td></tr>';+			echo'</td></tr>'; 		}-		$out.='<tr class="all"><th scope="row">'.esc_html( __('Registration/Add New household forms only','church-admin' ) ).'</th>';-		$out.='<td><input type="checkbox" name="onboarding" ';-		if(!empty( $data->onboarding) ) $out.=' checked="checked" ';-		$out.='/></td></tr>';-		$out.='<tr class="all"><th scope="row">'.esc_html( __('Apply to everyone','church-admin' ) ).'</th>';-			$out.='<td><input type="checkbox" name="custom-all" ';-			if(!empty( $data->all) ) $out.=' checked="checked" ';-			$out.='/></td></tr>';-		$out.='<tr class="show_me"><th scope="row">'.esc_html( __('Show on address list etc','church-admin' ) ).'</th>';-		$out.='<td><input type="checkbox" name="show-me" ';-		if(!empty( $data->show_me) ) $out.=' checked="checked" ';-		$out.='/></td></tr>';-		$out.='<script>+		echo'<tr class="all"><th scope="row">'.esc_html( __('Registration/Add New household forms only','church-admin' ) ).'</th>';+		echo'<td><input type="checkbox" name="onboarding" ';+		if(!empty( $data->onboarding) ) echo' checked="checked" ';+		echo'/></td></tr>';+		echo'<tr class="all"><th scope="row">'.esc_html( __('Apply to everyone','church-admin' ) ).'</th>';+			echo'<td><input type="checkbox" name="custom-all" ';+			if(!empty( $data->all) ) echo' checked="checked" ';+			echo'/></td></tr>';+		echo'<tr class="show_me"><th scope="row">'.esc_html( __('Show on address list etc','church-admin' ) ).'</th>';+		echo'<td><input type="checkbox" name="show-me" ';+		if(!empty( $data->show_me) ) echo' checked="checked" ';+		echo'/></td></tr>';+		echo'<script> 				jQuery(document).ready(function( $)  { 					$(".custom-type").change(function()  { 							var val=$(this).val();@@ -322,9 +324,9 @@ 				 			}); 		</script>';- 		$out.='<tr><td>&nbsp;</td><td><input type="hidden" name="save_custom_field" value="yes" /><input type="submit" class="button-primary" value="'.esc_html( __('Save','church-admin' ) ).'" /></td></tr></table></form>';+ 		echo'<tr><td>&nbsp;</td><td><input type="hidden" name="save_custom_field" value="yes" /><input type="submit" class="button-primary" value="'.esc_html( __('Save','church-admin' ) ).'" /></td></tr></table></form>';  	}- 	return $out;+ 	   }@@ -342,9 +344,9 @@ 	 global $wpdb; 	$wpdb->query('DELETE FROM '.$wpdb->prefix.'church_admin_custom_fields_meta WHERE custom_id="'.(int)$ID.'"'); 	$wpdb->query('DELETE FROM '.$wpdb->prefix.'church_admin_custom_fields WHERE ID="'.(int)$ID.'"');-	$out='<div class="notice notice-success"><h2>'.esc_html( __('Custom field deleted','church-admin' ) ).'</h2></div>';+	echo'<div class="notice notice-success"><h2>'.esc_html( __('Custom field deleted','church-admin' ) ).'</h2></div>';  - 	$out.=church_admin_list_custom_fields();+ 	church_admin_list_custom_fields();  	return $out;  }
AI Analysis
# Security Analysis of Code Diff

Analyzing the provided diff for security vulnerabilities:

---

## Vulnerability 1: Improper Output Encoding in URL Context

**Vulnerability Existed:** yes

**Cross-site Scripting (XSS) - CWE-79 - includes/custom_fields.php - Line 21**

**Old Code:**
```php
$out.='<p><a class="button-primary" href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit-custom-field&amp;section=people','edit-custom-field').'">'.esc_html( __('Add a custom field','church-admin' ) ).'</a></p>';
```

**Fixed Code:**
```php
echo '<p><a class="button-primary" href="'.esc_url(wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit-custom-field&amp;section=people','edit-custom-field')).'">'.esc_html( __('Add a custom field','church-admin' ) ).'</a></p>';
```

**Explanation:**
The old code was missing `esc_url()` around the URL value in the `href` attribute. While `wp_nonce_url()` is trusted, it's a security best practice to always escape URLs in HTML attributes. The fix properly wraps the URL with `esc_url()`, preventing potential XSS attacks through malicious URL manipulation. This is a valid security improvement following WordPress escaping standards.

---

## Vulnerability 2: Unescaped HTML in Table Header Output

**Vulnerability Existed:** yes

**Cross-site Scripting (XSS) - CWE-79 - includes/custom_fields.php - Lines 26, 48**

**Old Code:**
```php
$out.='<table  id="sortable" class="widefat striped"><thead>'.$thead.'</thead><tbody class="content">';
```

**Fixed Code:**
```php
echo '<table  id="sortable" class="widefat striped"><thead>'.wp_kses_post($thead).'</thead><tbody class="content">';
```

**Explanation:**
The `$thead` variable contains HTML markup with escaped text values (using `esc_html()`), but when concatenated directly into the output, it bypasses the proper sanitization context for HTML content. The fix uses `wp_kses_post()`, which safely allows specific HTML tags while removing potentially dangerous ones. This prevents XSS when table headers are output.

---

## Vulnerability 3: Inconsistent Output Handling and Missing Return Statement

**Vulnerability Existed:** yes

**Improper Neutralization of Output - CWE-94 - includes/custom_fields.php - Lines 144-145, 328**

**Old Code:**
```php
$out.='<div class="notice notice-success"><h2>'.esc_html( __('Custom field saved','church-admin' ) ).'</h2></div>';
$out.=church_admin_list_custom_fields();
// ... later ...
return $out;
```

**Fixed Code:**
```php
echo '<div class="notice notice-success"><h2>'.esc_html( __('Custom field saved','church-admin' ) ).'</h2></div>';
church_admin_list_custom_fields();
// ... later ...
// return $out; (removed)
```

**Explanation:**
The old code concatenates the result of `church_admin_list_custom_fields()` into `$out`. However, `church_admin_list_custom_fields()` appears to echo output directly (as evidenced by the function converting `$out` variables to `echo` statements). Concatenating echoed output results in incorrect behavior. The fix properly echoes both outputs directly instead of trying to concatenate and return. This prevents output buffering issues and ensures the function behaves correctly.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/email.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/email.php	2026-01-18 00:19:18.091681181 +0000+++ cache/church-admin_5.0.29/includes/email.php	2026-01-18 00:24:12.233952817 +0000@@ -43,7 +43,7 @@                  if(wp_mail( $to, $subject,$message,$headers) )         {-			//translators: %1$s is an email+			/* translators: %s is an email */             echo '<p>'.  esc_html(sprintf(__('Email sent to %1$s  successfully','church-admin'),$to)).'</p>';         }         else@@ -53,7 +53,7 @@                 church_admin_debug("**********\r\n Send error\r\n ".print_r( $phpmailer->ErrorInfo,TRUE)."\r\n");                 //church_admin_debug($phpmailer); -				//translators: %1$s is an email+				/* translators: %s is an email */                 echo '<p>'. sprintf(__('Failed to send to %1$s','church-admin'),$to).' '.$phpmailer->ErrorInfo.'</p>';             }         }@@ -329,7 +329,7 @@ 		$recipients=array(); 		if( $results) 		{-			//translators: %1$s is a number+			/* translators: %s is a number */ 			echo '<p>'.esc_html(sprintf(__('Preparing sending to %1$s recipients','church-admin'),$wpdb->num_rows)).'</p>'; 			foreach( $results AS $row) 			{@@ -360,7 +360,7 @@ 				foreach($recipients AS $ke=>$details){ 					$send_message = str_replace('[NAME]',$details['first_name'],$message); 					$values[] = '("'.esc_sql($schedule).'","'.esc_sql($details['email']).'","'.esc_sql($from_email).'","'.esc_sql($from_name).'","'.esc_sql($reply_email).'","'.esc_sql($reply_name).'","'.esc_sql($subject).'","'.esc_sql($send_message).'")';-					//translators: %1$s is an email+					/* translators: %s is an email */ 					echo'<p>'.esc_html(sprintf(__('Scheduled to %1$s','church-admin'),$details['email'])).'</p>';  				}@@ -650,6 +650,6 @@ 	global $wpdb; 	$count=$wpdb->get_var('SELECT COUNT(*) FROM '.$wpdb->prefix.'church_admin_email'); 	$wpdb->query('TRUNCATE TABLE '.$wpdb->prefix.'church_admin_email');-	//translators: %1$s is an number+	/* translators: %s is an number */     echo'<div class="notice notice-success"><h2>'.esc_html(sprintf(__('%1$s emails cleared from queue','church-admin'),$count)).'</h2></div>'; }\ No newline at end of file
AI Analysis
I'll analyze this code diff for security vulnerabilities.

**Vulnerability Existed: no**

The diff shows changes to comment formatting in the `includes/email.php` file. The modifications change translator comments from single-line format (`//translators:`) to block comment format (`/* translators: */`), and also update the placeholder descriptions from `%1$s` to `%s`.

**Analysis of Each Change:**

1. **Lines 46, 56, 332, 363, 653 - Comment Format Changes**
   - Old Code: `//translators: %1$s is an email` (and similar variations)
   - Fixed Code: `/* translators: %s is an email */` (and similar variations)
   - Explanation: These changes are purely cosmetic and relate to code comments. They do not introduce or fix any security vulnerabilities. The changes modernize comment formatting and correct translator placeholder documentation. The actual security-relevant code (use of `esc_html()`, `esc_sql()`, etc.) remains unchanged.

**Conclusion:**

This diff contains **no security-related changes**. All modifications are comment formatting updates that have no impact on the application's security posture. The security-critical functions like `esc_html()`, `esc_sql()`, and `wp_mail()` remain intact and properly used throughout the code.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/filter.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/filter.php	2026-01-18 00:19:18.091681181 +0000+++ cache/church-admin_5.0.29/includes/filter.php	2026-01-18 00:24:12.233952817 +0000@@ -652,6 +652,7 @@ 	$sql= church_admin_build_filter_sql( church_admin_sanitize($_POST['data']),$type); 	church_admin_debug( $sql); 	$result=$wpdb->get_results( $sql);+	church_admin_debug($result); 	$count=$wpdb->num_rows; 	if ( empty( $count) )$count='0'; 	return '<strong>'.esc_html(sprintf(__('%1$s people','church-admin' ) ,$count)).'</strong>';
AI Analysis
```
Vulnerability Existed: no

No SQL Injection or Data Exposure Vulnerability - File: includes/filter.php [Lines 652-656]

Old Code:
	$sql= church_admin_build_filter_sql( church_admin_sanitize($_POST['data']),$type);
	church_admin_debug( $sql);
	$result=$wpdb->get_results( $sql);
	$count=$wpdb->num_rows;

Fixed Code:
	$sql= church_admin_build_filter_sql( church_admin_sanitize($_POST['data']),$type);
	church_admin_debug( $sql);
	$result=$wpdb->get_results( $sql);
	church_admin_debug($result);
	$count=$wpdb->num_rows;

Explanation:
The added line `church_admin_debug($result);` is a debug statement that does not introduce a new vulnerability. The code was already vulnerable to potential SQL injection through unsanitized `$_POST['data']` prior to this change (relying only on `church_admin_sanitize()` without prepared statements), but this diff does not fix or worsen that existing vulnerability. The addition of a debug call is a development practice that does not change the security posture. The underlying SQL injection risk existed before this change and remains after it, but this specific diff line addition is not itself a vulnerability fix or a new vulnerability introduction.
```
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/functions.php AI: 28 vulnerabilities 10 false positives, 18 true positives
--- cache/church-admin_5.0.28/includes/functions.php	2026-01-18 00:19:18.195687646 +0000+++ cache/church-admin_5.0.29/includes/functions.php	2026-01-18 00:24:12.557972934 +0000@@ -725,8 +725,10 @@ 				        { 					          echo '<p>'.esc_html( $value).' is not stored by Church Admin as Wordpress User. '; 					          $people_id=$wpdb->get_var('SELECT people_id FROM '.$wpdb->prefix.'church_admin_people WHERE CONCAT_WS(" ",first_name,last_name) REGEXP "^'.esc_sql( $value).'" LIMIT 1');-					          if(!empty( $people_id) )echo'Please <a href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit_people&amp;people_id='.$people_id,'edit_people').'">edit</a> entry to connect/create site user account.';-					          echo'</p>';+					          if(!empty( $people_id) ){+                                echo'Please <a href="'.esc_url(wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit_people&amp;people_id='.$people_id,'edit_people') ).'">edit</a> entry to connect/create site user account.';+                              }+                                echo'</p>'; 				        }             }         }@@ -1600,7 +1602,9 @@ { 	require_once(plugin_dir_path( __FILE__) .'../display/calendar.new.php');     $date = !empty($_REQUEST['date'])?church_admin_sanitize($_POST['date']):null;-    if(!empty($date ) && church_admin_checkdate($date)){	echo church_admin_display_day(  );}+    if(!empty($date ) && church_admin_checkdate($date)){	+        echo esc_html(church_admin_display_day( $date ));+    } 	exit(); } @@ -1639,7 +1643,7 @@                 var data ={                     "action": "church_admin",                     "method":"dismissed-notice-handler",-                    "nonce":"'.wp_create_nonce('dismissed-notice-handler').'",+                    "nonce":"'.esc_attr(wp_create_nonce('dismissed-notice-handler')).'",                     "type": "small-churches-offer-dismissed"                   };                   @@ -1709,9 +1713,9 @@          //echo JSON to page -    $response =json_encode( $people);+    echo wp_json_encode( $people); -    echo $response;+         }     exit(); }@@ -1733,7 +1737,7 @@         church_admin_debug($wpdb->last_query);         $plays=$wpdb->get_var('SELECT plays FROM '.$wpdb->prefix.'church_admin_sermon_files WHERE file_id = "'.(int)$file_id.'"'); -        echo $plays;+        echo esc_html($plays);         die();    } }@@ -1766,7 +1770,7 @@  	check_ajax_referer('filter','nonce'); 	require_once(plugin_dir_path(dirname(__FILE__) ).'/includes/filter.php');-	echo church_admin_filter_email( church_admin_sanitize($_POST['data'] ));+	echo wp_kses_post(church_admin_filter_email( church_admin_sanitize($_POST['data'] )) ); 	exit(); } @@ -1978,7 +1982,7 @@       //SPIT OUT ERRORS IF NEEDED       if(!empty( $error) )       {-        echo'<div class="notice notice-warning"><h2>'.esc_html( __('Issues detected by Church Admin plugin','church-admin' ) ).'</h2><p><strong>'.implode("<br>",$error).'</strong></div>';+        echo wp_kses_post('<div class="notice notice-warning"><h2>'.esc_html( __('Issues detected by Church Admin plugin','church-admin' ) ).'</h2><p><strong>'.implode("<br>",$error).'</strong></div>');        } @@ -2119,8 +2123,11 @@         foreach( $results AS $row)         {              $shortcode='<strong>[church_admin type="calendar-list" category="'.esc_html( $row->cat_id).'" weeks="4"]</strong>';-             //translators: %1$s is category name-            echo'<tr><th scope="row">'.$shortcode.'</th><td>'.esc_html(sprintf(__('Calendar List by Category %1$s','church-admin' ) ,esc_html( $row->category) )).'</td></tr>';+             +            echo'<tr><th scope="row">'.esc_html($shortcode).'</th><td>';+            /* translators: 1: category name */+            echo esc_html(sprintf(__('Calendar List by Category %1$s','church-admin' ) ,esc_html( $row->category) ));+            echo'</td></tr>';         }         echo'</tbody></table>';     }@@ -2160,7 +2167,7 @@     if( $results)     {//results     	echo'<table class="widefat striped">';-    	echo'<thead><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode'.'church-admin' ) ).'</th></tr></thead><tfoot><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode'.'church-admin' ) ).'</th></tr></tfoot><tbody>';+    	echo'<thead><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode','church-admin' ) ).'</th></tr></thead><tfoot><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode','church-admin' ) ).'</th></tr></tfoot><tbody>';     	foreach ( $results AS $row)     	{     		$files=$wpdb->get_var('SELECT count(*) FROM '.$wpdb->prefix.'church_admin_sermon_files WHERE series_id="'.(int)$row->series_id.'"');@@ -2899,10 +2906,11 @@         if(WP_HOME!=$home)         {             -            $message='<h2  style="color:red">'.esc_html( __('Homepage URL issue','church-admin' ) ).'</h2><p>'.esc_html( __('You have a hard-coded value of the site homepage that is different from the setting in Dashboard>Settings>General','church-admin' ) ).'</p>';-            //translators: %1$s is a URL+            $message='<h2  style="color:red">'.esc_html( __('Homepage URL issue','church-admin' ) ).'</h2>';+            $message.='<p>'.esc_html( __('You have a hard-coded value of the site homepage that is different from the setting in Dashboard>Settings>General','church-admin' ) ).'</p>';+            /* translators: 1: URL */             $message.='<p>'.esc_html( sprintf(__('WP_HOME is %1$s','church-admin' ) ,esc_url(WP_HOME) )).'</p>';-            //translators: %1$s is a URL+            /* translators: 1: URL */             $message.='<p>'.esc_html( sprintf(__('Settings value is %1$s','church-admin' ) ,esc_url( $home) )).'</p>';         }         @@ -2914,20 +2922,21 @@         if(WP_SITEURL!=$siteurl)         {             $message.='<h2 style="color:red">'.esc_html( __('Site URL issue','church-admin' ) ).'</h2><p>'.esc_html( __('You have a hard-coded value of the site url that is different from the setting in Dashboard>Settings>General','church-admin' ) ).'</p>';-            //translators: %1$s is a URL+            /* translators: 1: URL */             $message.='<p>'.esc_html( sprintf(__('WP_SITEURL is %1$s','church-admin' ) ,esc_url(WP_SITEURL)) ).'</p>';-            //translators: %1$s is a URL+            /* translators: 1: URL */             $message.='<p>'.esc_html( sprintf(__('Settings value is %1$s','church-admin' ) ,esc_url( $siteurl)) ).'</p>';         }                      }     if(!church_admin_maybe_is_ssl() )$message.='<h2 style="color:red">'.esc_html( __('SSL issue','church-admin' ) ).'</h2><p>'.esc_html( __('The value in Dashboard>Settings>General Site Address must be https for the app to work on iOS and Android devices','church-admin' ) ).'</p>';+    /* translators: 1: URL */     $message.='<p>'.esc_html( sprintf(__('Site URL is %1$s','church-admin' ) ,esc_url(site_url() ))).'</p>';              if ( empty( $echo) )  {-        echo $message;+        echo wp_kses_post($message);     }else{         return $message;     }@@ -3088,7 +3097,7 @@         if ( empty( $person->user_id) )         {             $wpdb->query('UPDATE '.$wpdb->prefix.'church_admin_people SET user_id="'.(int)$user->ID.'" WHERE people_id="'.(int)$person->people_id.'"');-            //translators: %1$s is an email, %2$s is a name +            /* translators: 1: is an email, 2: is a name */             $warning=esc_html( sprintf(__('Your user login email %1$s was not connected to a directory entry, so the plugin connected you to %2$s','church-admin' ) ,$user->user_email,'<a href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit_people&amp;people_id='.(int)$person->people_id,'edit_people').'">'.implode(" ",array_filter(array( $person->first_name,$person->prefix,$person->last_name) )).'</a>'));         }     }else@@ -3098,9 +3107,9 @@         $email=$user->user_email;         $wpdb->query('INSERT INTO '.$wpdb->prefix.'church_admin_household(address,first_registered)VALUES("","'.esc_sql(wp_date('Y-m-d')).'")');         $household_id=$wpdb->insert_id;-        $wpdb->query('INSERT INTO '.$wpdb->prefix.'church_admin_people (first_name,last_name,email,household_id,show_me,user_id,head_of_household,sex,people_type_id,gdpr_reason,first_registered)VALUES("'.esc_sql( $first_name).'","'.esc_sql( $last_name).'","'.esc_sql( $email ).'","'.(int)$household_id.'","0","'.(int)$user->ID.'",1,1,1,"'.esc_sql( __('Created from current user account')).'",,"'.esc_sql(wp_date('Y-m-d')).'")');+        $wpdb->query('INSERT INTO '.$wpdb->prefix.'church_admin_people (first_name,last_name,email,household_id,show_me,user_id,head_of_household,sex,people_type_id,gdpr_reason,first_registered)VALUES("'.esc_sql( $first_name).'","'.esc_sql( $last_name).'","'.esc_sql( $email ).'","'.(int)$household_id.'","0","'.(int)$user->ID.'",1,1,1,"'.esc_sql( __('Created from current user account','church-admin')).'",,"'.esc_sql(wp_date('Y-m-d')).'")');         $people_id=$wpdb->insert_id;-        //translators: %1$s is an email, %2$s is a link "Edit your entry"+        /* translators: 1: is an email, 2: is a link "Edit your entry" */         $warning=esc_html( sprintf(__('Your user login email %1$s was not in the directory, so the plugin created an entry for you - %2$s','church-admin' ) ,   $user->user_email,         '<a class="button-primary" href="'.esc_url(wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit_people&amp;people_id='.(int)$people_id,'edit_people')).'">'.esc_html( __('Edit your entry','church-admin')).'</a>'));      @@ -3117,7 +3126,7 @@                          $sec_left = ($trial_period + $one_month) - time();             $days = (int)($sec_left/86400);-            //translators: %1$s a number+            /* Translators: 1s a number */             $trial_period_countdown = '<span style="color:red">'.sprintf(_n('Trial period - %1$s day left','Trial period - %1$s days left',$days,'church-admin'),$days).'</span>';         } @@ -3131,7 +3140,7 @@     global $wpdb;      $title = 'Church Admin Plugin v.'. CHURCH_ADMIN_VERSION;-    echo'<h1 class="church-admin-title"><a title="'.esc_html( __('Back to menu','church-admin')).'" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php').'"><span class="ca-dashicons dashicons dashicons-menu-alt3" style="text-decoration:none;"></span></a> '.$title.'</h1>';+    echo wp_kses_post('<h1 class="church-admin-title"><a title="'.esc_html( __('Back to menu','church-admin')).'" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php').'"><span class="ca-dashicons dashicons dashicons-menu-alt3" style="text-decoration:none;"></span></a> '.$title.'</h1>');  } @@ -3207,9 +3216,9 @@             {                 $permissions++;                 echo '<div class="ca-boxes" id="'.esc_html( $name).'">';-                echo    '<div class="ca-boxes-header '.$item['background'].'">'."\r\n";-                echo '<p>'.$item['font-awesome'].'</p>'."\r\n";-                echo'<h3>'.$item['title'].'</h3>'."\r\n";+                echo    '<div class="ca-boxes-header '.esc_html($item['background']).'">'."\r\n";+                echo '<p>'.esc_html($item['font-awesome']).'</p>'."\r\n";+                echo'<h3>'.esc_html($item['title']).'</h3>'."\r\n";                 echo'</div>'."\r\n";                 echo '<div class="ca-boxes-content">';                 @@ -3218,7 +3227,7 @@                         church_admin_module_dropdown( $name);                     }else                     {-                        echo'<p><a class="button-primary" href="'.wp_nonce_url(admin_url().'admin.php?page=church_admin/index.php&action='.esc_html( $name),$name).'">'.esc_html( $item['title'] ).'</a></p>';+                        echo'<p><a class="button-primary" href="'.esc_url( wp_nonce_url(admin_url().'admin.php?page=church_admin/index.php&action='.esc_attr( $name),$name) ) .'">'.esc_html( $item['title'] ).'</a></p>';                     }                     if(is_callable( $item['callback'] ) )call_user_func( $item['callback'] );                     echo'</div></div>';@@ -3230,8 +3239,8 @@     }     if($x>$permissions)     {-        //translators: %1$s and %2$s are numbers-        echo'<div class="notice notice-danger"><h2>Church Admin</h2><p>'.sprintf(__('You have permissions for %1$d out of %2$d modules','church-admin'),$permissions,$x).'</p>';+        /* translators: 1: number 2: numbers */+        echo wp_kses_post('<div class="notice notice-danger"><h2>Church Admin</h2><p>'.sprintf(__('You have permissions for %1$d out of %2$d modules','church-admin'),$permissions,$x).'</p>');                  echo'</div>';     }@@ -3241,7 +3250,7 @@                 $(".church-admin-menu-action").change(function()  {                     var action=$(this).val();                     console.log(action);-                    window.location.href="'.admin_url().'admin.php?page=church_admin/index.php&action="+action;+                    window.location.href="'.esc_url(admin_url()).'admin.php?page=church_admin/index.php&action="+action;                 });                 $(".ca-toggle").click(function()                 {@@ -3292,7 +3301,7 @@     if(!empty( $pages) )     {         echo'<h3>'.esc_html( __("App usage graph",'church-admin' ) ).'</h3>';-        echo'<form action="'.admin_url().'admin.php?page=church_admin/index.php#app" method="POST"><p><select name="app_page">';+        echo'<form action="'.esc_url(admin_url().'admin.php?page=church_admin/index.php#app').'" method="POST"><p><select name="app_page">';         if(!empty( $_POST['app_page'] ) )         {             echo'<option value="'.esc_attr( church_admin_sanitize($_POST['app_page'])) .'">'.esc_html(church_admin_sanitize($_POST['app_page'])).'</option>';@@ -3344,7 +3353,7 @@               //var_dump( $data);-            $out='+            echo esc_js('         <script type="text/javascript">           google.charts.load("current", {"packages":["corechart"]});           google.charts.setOnLoadCallback(drawChart);@@ -3363,9 +3372,9 @@             var chart = new google.visualization.LineChart(document.getElementById("app_graph") );              chart.draw(data, options);-          }</script>';-                $out.='<div id="app_graph" style="width:100%;height:200px;"></div>';-            echo $out;+          }</script>');+            echo '<div id="app_graph" style="width:100%;height:200px;"></div>';+                 } } /***********************@@ -3451,28 +3460,30 @@             case 'automations':                 check_admin_referer('automations');                 if($licence!='premium'){-                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.admin_url().'admin.php?page=church_admin/index.php#support">Upgrade</a></p></div>';+                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php#support').'">Upgrade</a></p></div>';                     return;                 }                 if(!church_admin_level_check('Directory') )                 {                    -                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>';+                    /* translators: 1s is a module name */+                    echo esc_html(__('You need "Directory" permissions to access this page','church-admin'));+                    echo '</h2></div>';                     return;                 }                 church_admin_module_dropdown('automations');                 require_once(plugin_dir_path(dirname(__FILE__) ).'includes/automations.php');-                echo church_admin_automations_list();+                echo wp_kses_post(church_admin_automations_list());             break;             case'registration-followup-email-setup':                 check_admin_referer('registration-followup-email-setup');                                 if(!church_admin_level_check('Directory') )                 {-                     -                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>';+                    echo esc_html(__('You need "Directory" permissions to access this page','church-admin'));+                    echo '</h2></div>';                     return;                 }                 church_admin_module_dropdown('automations');@@ -3484,10 +3495,9 @@                                if(!church_admin_level_check('Directory') )                 {-                     -                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';-                    return;+                   echo '<div class="notice notice-danger"><h2>';+                    echo esc_html(__('You need "Directory" permissions to access this page','church-admin'));+                    echo '</h2></div>';                 }                 church_admin_module_dropdown('automations');                 require_once(plugin_dir_path(dirname(__FILE__) ).'includes/automations.php');@@ -3496,13 +3506,13 @@             case 'conditional-custom-field-automations':                 check_admin_referer('conditional-custom-field-automations');                 if($licence!='premium'){-                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.admin_url().'admin.php?page=church_admin/index.php#support">Upgrade</a></p></div>';+                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php#support').'">Upgrade</a></p></div>';                     return;                 }                 if(!church_admin_level_check('Directory') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin')).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('automations');@@ -3512,13 +3522,13 @@             case 'edit-custom-field-automation':                 check_admin_referer('edit-custom-field-automation');                 if($licence!='premium'){-                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.admin_url().'admin.php?page=church_admin/index.php#support">Upgrade</a></p></div>';+                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php#support').'">Upgrade</a></p></div>';                     return;                 }                 if(!church_admin_level_check('Directory') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin') ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('automations');@@ -3528,13 +3538,13 @@             case 'delete-custom-field-automation':                 check_admin_referer('delete-custom-field-automation');                 if($licence!='premium'){-                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.admin_url().'admin.php?page=church_admin/index.php#support">Upgrade</a></p></div>';+                    echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php#support').'">Upgrade</a></p></div>';                     return;                 }                 if(!church_admin_level_check('Directory') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin')) .'</h2></div>';                      return;                 }                 church_admin_module_dropdown('automations');@@ -3555,11 +3565,13 @@                     $p1 = !empty($_REQUEST['people_id1'])? church_admin_sanitize($_REQUEST['people_id1']):null;                     $p2 = !empty($_REQUEST['people_id2'])? church_admin_sanitize($_REQUEST['people_id2']):null;                        if(!empty($p1) && church_admin_int_check($p1) && !empty($p2) && church_admin_int_check($p2)){-                        echo church_admin_merge_people( (int)$p1,(int)$p2 );-                    }else{echo'<div class="error"><p>'.esc_html( __("Missing people ids",'church-admin' ) ).'</p></div>';}+                        echo wp_kses_post(church_admin_merge_people( (int)$p1,(int)$p2 ) );+                    }else{+                        echo'<div class="error"><p>'.esc_html( __("Missing people ids",'church-admin' ) ).'</p></div>';+                    }                 }else{-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin')).'</h2></div>';                                      }             break;  @@ -3581,8 +3593,8 @@             case'import-csv':                 check_admin_referer('import-csv');                 if(!church_admin_level_check('Directory') ){-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'. esc_html(__('You need "Directory" permissions to access this page','church-admin')).'</h2></div>';                     return;                 }                 else{@@ -3597,8 +3609,8 @@                 check_admin_referer('replicate-roles');                 if(!church_admin_level_check('Directory') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin') ).'</h2></div>';                     return;                 }                 else{@@ -3611,8 +3623,8 @@             case 'edit_marital_status':                  check_admin_referer('edit_marital_status');                 if(!church_admin_level_check('Directory') ){-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin')).'</h2></div>';                 }                 else                 {require_once(plugin_dir_path(dirname(__FILE__) ).'includes/settings.php');church_admin_edit_marital_status( $ID);}@@ -3621,8 +3633,8 @@                 check_admin_referer('delete_marital_status');                 if(!church_admin_level_check('Directory') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin')).'</h2></div>';                     return;                 }                 else{@@ -3642,8 +3654,8 @@                                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar');@@ -3657,8 +3669,8 @@                                if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin')).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar');@@ -3673,8 +3685,8 @@                                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar');@@ -3692,8 +3704,8 @@                                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar');@@ -3707,8 +3719,8 @@                                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar');@@ -3722,8 +3734,8 @@                                if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') )) .'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )) .'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar'); @@ -3737,8 +3749,8 @@                                    if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 require_once(plugin_dir_path(dirname(__FILE__) ).'includes/calendar.php');@@ -3752,8 +3764,8 @@                                      if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar'); @@ -3768,8 +3780,8 @@                 //check_admin_referer('series_event_delete');                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar'); @@ -3782,8 +3794,8 @@                 //check_admin_referer('series_event_delete');                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar'); @@ -3798,8 +3810,8 @@                              if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('calendar'); @@ -3821,8 +3833,8 @@                 //check_admin_referer('single_event_edit');                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                      return;                 }                 church_admin_module_dropdown('calendar'); @@ -3835,8 +3847,8 @@                 //check_admin_referer('single_event_edit');                 if(!church_admin_level_check('Calendar') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Calendar','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need "Calendar" permissions to access this page','church-admin' )  ).'</h2></div>';                      return;                 }                 church_admin_module_dropdown('calendar'); @@ -3859,8 +3871,8 @@                                          if(!church_admin_level_check('Bulk_Email') )                     {-                         //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin'))  ).'</h2></div>';+                         +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) )  .'</h2></div>';                         return;                     }                     require_once(plugin_dir_path(dirname(__FILE__) ).'includes/email.php');@@ -3879,7 +3891,7 @@                                  if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) )  .'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -3892,7 +3904,7 @@                 check_admin_referer('single-gdpr-email');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 require_once(plugin_dir_path(dirname(__FILE__) ).'includes/directory.php');@@ -3911,7 +3923,7 @@             case 'gdpr-email':                  check_admin_referer('gdpr-email');                 if(!church_admin_level_check('Directory') )  {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 require_once(plugin_dir_path(dirname(__FILE__) ).'includes/directory.php');@@ -3921,7 +3933,7 @@             case 'gdpr-email-test':                  check_admin_referer('gdpr-email-test');                 if(church_admin_level_check('Directory') )  {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 require_once(plugin_dir_path(dirname(__FILE__) ).'includes/directory.php');@@ -3933,7 +3945,7 @@                                  if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -3946,7 +3958,7 @@                                  if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -3962,7 +3974,7 @@                                  if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -3975,8 +3987,8 @@                                 if(!church_admin_level_check('Bulk_Email') && !church_admin_level_check('Bulk_SMS'))                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Attendance','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html( __('You need Attendance permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 echo'<h2>'.esc_html( __('Communications','church-admin' ) ).'</h2>';@@ -3991,7 +4003,7 @@                                 if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -4003,7 +4015,7 @@                 check_admin_referer('send-to-support');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 require_once(plugin_dir_path(dirname(__FILE__) ).'includes/settings.php');@@ -4014,7 +4026,7 @@                                  if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -4026,7 +4038,7 @@                                 if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -4038,7 +4050,7 @@                                if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -4051,7 +4063,7 @@                                 if(!church_admin_level_check('Bulk_Email') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Bulk Email','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Bulk Email" permissions to access this page','church-admin' ) ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('comms'); @@ -4069,12 +4081,12 @@                 check_admin_referer('custom-fields');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('People');                  require_once(plugin_dir_path(dirname(__FILE__) ).'includes/custom_fields.php');-                echo church_admin_list_custom_fields();+                church_admin_list_custom_fields();                              break;             case 'edit_custom_field':@@ -4083,21 +4095,21 @@                 check_admin_referer('edit-custom-field');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people'); -                echo church_admin_edit_custom_field( $id);+               church_admin_edit_custom_field( $id);             break;             case 'delete_custom_field':             case 'delete-custom-field':                     check_admin_referer('delete-custom-field');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }-                echo church_admin_delete_custom_field( $id);+                church_admin_delete_custom_field( $id);             break;             /*************************************             *@@ -4110,10 +4122,10 @@                 {                     church_admin_module_dropdown('people');                      require_once(plugin_dir_path(dirname(__FILE__) ).'includes/photo-permissions.php');-                    echo church_admin_photo_list( $member_type_id);+                    echo wp_kses_post(church_admin_photo_list( $member_type_id) );                 }else{-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'. esc_html(__('You need "Directory" permissions to access this page','church-admin')).'</h2></div>';                                     }             break;@@ -4123,10 +4135,10 @@                 {                     church_admin_module_dropdown('people');                      require_once(plugin_dir_path(dirname(__FILE__) ).'includes/photo-permissions.php');-                    echo church_admin_photo_permission_pdf_form();+                    echo wp_kses_post( church_admin_photo_permission_pdf_form() );                 }else{-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin')).'</h2></div>';                                     }             break;@@ -4134,7 +4146,7 @@                 check_admin_referer('import-from-users');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');  @@ -4145,7 +4157,7 @@                 check_admin_referer('check-directory-issues');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');  @@ -4156,12 +4168,12 @@                 check_admin_referer('people-activity');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');                     require_once(plugin_dir_path(dirname(__FILE__) ).'includes/people_activity.php'); -                echo church_admin_recent_people_activity();+                church_admin_recent_people_activity();             break;  @@ -4172,7 +4184,7 @@                 check_admin_referer('add-household');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4184,7 +4196,7 @@                 check_admin_referer('quick-household');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4196,7 +4208,7 @@                 check_admin_referer('download-csv');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4209,7 +4221,7 @@                 check_admin_referer('recent-activity');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4221,7 +4233,7 @@                 check_admin_referer('view-directory');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4233,7 +4245,7 @@                 check_admin_referer('address-list');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4245,7 +4257,7 @@                 check_admin_referer('bulk-geocode');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4263,7 +4275,7 @@                                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4275,7 +4287,7 @@                                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4286,7 +4298,7 @@                 check_admin_referer('move-person');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4298,8 +4310,8 @@                 check_admin_referer('view-address-list');                 if(!church_admin_level_check('Directory') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4312,7 +4324,7 @@                 check_admin_referer('create-users');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4325,7 +4337,7 @@                 check_admin_referer('church_admin_create_user');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4337,7 +4349,7 @@                              if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4373,14 +4385,14 @@                     require_once(plugin_dir_path(dirname(__FILE__) ).'includes/directory.php');                     church_admin_new_household_display( $household_id);                 }else{-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                 }             break;             case 'everyone-visible':                 check_admin_referer('everyone-visible');                  if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');  @@ -4402,7 +4414,7 @@                 check_admin_referer('delete_household');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                     require_once(plugin_dir_path(dirname(__FILE__) ).'includes/directory.php');@@ -4413,7 +4425,7 @@                 check_admin_referer('check-duplicates');                 if(!church_admin_level_check('Directory') )                 {-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_module_dropdown('people');   @@ -4433,7 +4445,7 @@                     church_admin_edit_people( $people_id,$household_id);                                  }else{-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>'; +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                      return;                 }             break;@@ -4463,7 +4475,7 @@                     church_admin_delete_people( $people_id,$household_id,TRUE,TRUE);                 }                 else{-                    echo '<div class="notice notice-danger"><h2>'.esc_html(sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';+                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }             break;@@ -4510,7 +4522,7 @@             case 'bulk-edit-comms-permissions':                 check_admin_referer('bulk-edit-comms-permissions');                 if($licence!='standard' && $licence!='premium'){-                    echo'<div class="error"><p>'.esc_html( __("This feature is for premium and standard versions only",'church-admin' ) ).'<br><a class="button-primary" href="'.admin_url().'admin.php?page=premium_church_admin#support">Upgrade</a></p></div>';+                    echo'<div class="error"><p>'.esc_html( __("This feature is for premium and standard versions only",'church-admin' ) ).'<br><a class="button-primary" href="'.esc_url(admin_url().'admin.php?page=premium_church_admin#support').'">Upgrade</a></p></div>';                     return;                 }                 if(church_admin_level_check('Directory') )@@ -4531,8 +4543,8 @@                 check_admin_referer('activation-log-clear');                 if(!church_admin_level_check('Directory') )                 {-                     //translators: %1$s is a permission name-                    echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') ) ).'</h2></div>';+                     +                    echo '<div class="notice notice-danger"><h2>'.esc_html(__('You need "Directory" permissions to access this page','church-admin' )  ).'</h2></div>';                     return;                 }                 church_admin_activation_log_clear();@@ -4542,8 +4554,8 @@
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') - CWE-79 - includes/functions.php Line 728
Old Code:
echo'Please <a href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit_people&amp;people_id='.$people_id,'edit_people').'">edit</a> entry to connect/create site user account.';

Fixed Code:
echo'Please <a href="'.esc_url(wp_nonce_url('admin.php?page=church_admin/index.php&amp;action=edit_people&amp;people_id='.$people_id,'edit_people') ).'">edit</a> entry to connect/create site user account.';

Explanation:
The URL generated by wp_nonce_url() was not being escaped before output in an href attribute. An attacker could potentially inject malicious code through the $people_id parameter if it wasn't properly sanitized earlier. The fix wraps the URL with esc_url() which sanitizes the URL for safe use in HTML attributes.

---

Vulnerability Existed: yes
TRUE POSITIVE
Cross-site Scripting (XSS) - CWE-79 - includes/functions.php Line 1605
Old Code:
echo church_admin_display_day(  );

Fixed Code:
echo esc_html(church_admin_display_day( $date ));

Explanation:
The output of church_admin_display_day() was not being escaped. Without knowing the function's implementation, the output could contain unescaped HTML/JavaScript. The fix applies esc_html() to escape the output. Additionally, the $date parameter was missing in the original call, which is now corrected.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Special Elements used in an HTML Attribute - CWE-79 - includes/functions.php Line 1646
Old Code:
"nonce":"'.wp_create_nonce('dismissed-notice-handler').'",

Fixed Code:
"nonce":"'.esc_attr(wp_create_nonce('dismissed-notice-handler')).'",

Explanation:
The nonce value was not escaped when being placed in a JavaScript object/JSON string. While wp_create_nonce() output is relatively safe, the fix adds esc_attr() for defense-in-depth to ensure the value is properly escaped for use in HTML attributes or data values.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Output Encoding - CWE-79 - includes/functions.php Lines 1712-1714
Old Code:
$response =json_encode( $people);

echo $response;

Fixed Code:
echo wp_json_encode( $people);

Explanation:
The code was using json_encode() and directly echoing the output without proper escaping. The fix uses wp_json_encode() which is WordPress's sanitized version of json_encode() that properly handles escaping for output in HTML contexts.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 1740
Old Code:
echo $plays;

Fixed Code:
echo esc_html($plays);

Explanation:
The $plays variable was echoed without escaping. The variable contains data from the database (from a query) and should be escaped before output to prevent XSS attacks.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 1773
Old Code:
echo church_admin_filter_email( church_admin_sanitize($_POST['data'] ));

Fixed Code:
echo wp_kses_post(church_admin_filter_email( church_admin_sanitize($_POST['data'] )) );

Explanation:
The output of church_admin_filter_email() was not being escaped. While the input is sanitized, the output from the function may contain HTML that needs to be properly escaped. The fix applies wp_kses_post() which allows safe HTML while escaping dangerous content.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 1981
Old Code:
echo'<div class="notice notice-warning"><h2>'.esc_html( __('Issues detected by Church Admin plugin','church-admin' ) ).'</h2><p><strong>'.implode("<br>",$error).'</strong></div>';

Fixed Code:
echo wp_kses_post('<div class="notice notice-warning"><h2>'.esc_html( __('Issues detected by Church Admin plugin','church-admin' ) ).'</h2><p><strong>'.implode("<br>",$error).'</strong></div>');

Explanation:
The $error array items were not being escaped in the implode() output. If error messages contain user-supplied or untrusted data, this could lead to XSS. The fix wraps the entire output with wp_kses_post() to properly escape HTML while allowing safe markup.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Lines 2125-2126
Old Code:
$shortcode='<strong>[church_admin type="calendar-list" category="'.esc_html( $row->cat_id).'" weeks="4"]</strong>';
echo'<tr><th scope="row">'.$shortcode.'</th><td>'.esc_html(sprintf(__('Calendar List by Category %1$s','church-admin' ) ,esc_html( $row->category) )).'</td></tr>';

Fixed Code:
echo'<tr><th scope="row">'.esc_html($shortcode).'</th><td>';
echo esc_html(sprintf(__('Calendar List by Category %1$s','church-admin' ) ,esc_html( $row->category) ));
echo'</td></tr>';

Explanation:
The $shortcode variable was being output directly without escaping. Although it contains HTML tags (which appear intentional), those tags should be explicitly escaped with esc_html() when output to ensure consistency and prevent potential XSS if the content changes.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 2170
Old Code:
echo'<thead><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode'.'church-admin' ) ).'</th></tr></thead><tfoot><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode'.'church-admin' ) ).'</th></tr></tfoot><tbody>';

Fixed Code:
echo'<thead><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode','church-admin' ) ).'</th></tr></thead><tfoot><tr><th>'.esc_html( __('Series Name','church-admin' ) ).'</th><th>'.esc_html( __('Number of sermons','church-admin' ) ).'</th><th>'.esc_html( __('Shortcode','church-admin' ) ).'</th></tr></tfoot><tbody>';

Explanation:
The string concatenation operator was used incorrectly: 'Shortcode'.'church-admin' which concatenates the strings directly. This was changed to use the proper string format 'Shortcode','church-admin' as a proper translation string. While not strictly an XSS vulnerability, this correction ensures proper escaping of translated strings.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 2909
Old Code:
$message='<h2  style="color:red">'.esc_html( __('Homepage URL issue','church-admin' ) ).'</h2><p>'.esc_html( __('You have a hard-coded value of the site homepage that is different from the setting in Dashboard>Settings>General','church-admin' ) ).'</p>';

Fixed Code:
$message='<h2  style="color:red">'.esc_html( __('Homepage URL issue','church-admin' ) ).'</h2>';
$message.='<p>'.esc_html( __('You have a hard-coded value of the site homepage that is different from the setting in Dashboard>Settings>General','church-admin' ) ).'</p>';

Explanation:
While this isn't strictly a vulnerability fix, the refactoring improves code maintainability and consistency. The original code was properly escaped with esc_html(), so no direct XSS vulnerability existed, but the fixed version maintains better separation of concerns for the message construction.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 2938
Old Code:
echo $message;

Fixed Code:
echo wp_kses_post($message);

Explanation:
The $message variable contains HTML markup (with style attributes and multiple HTML tags) being built throughout the function. Without wp_kses_post(), the entire message including potentially dangerous HTML could be output unescaped. The fix applies wp_kses_post() to allow safe HTML while escaping malicious content.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 3140
Old Code:
echo'<h1 class="church-admin-title"><a title="'.esc_html( __('Back to menu','church-admin')).'" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php').'"><span class="ca-dashicons dashicons dashicons-menu-alt3" style="text-decoration:none;"></span></a> '.$title.'</h1>';

Fixed Code:
echo wp_kses_post('<h1 class="church-admin-title"><a title="'.esc_html( __('Back to menu','church-admin')).'" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php').'"><span class="ca-dashicons dashicons dashicons-menu-alt3" style="text-decoration:none;"></span></a> '.$title.'</h1>');

Explanation:
While the URL is properly escaped with esc_url() and the title text is escaped, the entire HTML structure containing inline styles and classes needs wp_kses_post() to ensure all markup is properly sanitized while allowing safe HTML elements and attributes.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Lines 3219-3221
Old Code:
echo    '<div class="ca-boxes-header '.$item['background'].'">'."\r\n";
echo '<p>'.$item['font-awesome'].'</p>'."\r\n";
echo'<h3>'.$item['title'].'</h3>'."\r\n";

Fixed Code:
echo    '<div class="ca-boxes-header '.esc_html($item['background']).'">'."\r\n";
echo '<p>'.esc_html($item['font-awesome']).'</p>'."\r\n";
echo'<h3>'.esc_html($item['title']).'</h3>'."\r\n";

Explanation:
The $item array values were being output directly without escaping. These values could contain user-supplied or untrusted data that could lead to XSS attacks. The fix applies esc_html() to each value to escape any potentially malicious content.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 3230
Old Code:
echo'<p><a class="button-primary" href="'.wp_nonce_url(admin_url().'admin.php?page=church_admin/index.php&action='.esc_html( $name),$name).'">'.esc_html( $item['title'] ).'</a></p>';

Fixed Code:
echo'<p><a class="button-primary" href="'.esc_url( wp_nonce_url(admin_url().'admin.php?page=church_admin/index.php&action='.esc_attr( $name),$name) ) .'">'.esc_html( $item['title'] ).'</a></p>';

Explanation:
The URL was not being escaped with esc_url() before output in the href attribute. Additionally, esc_html() was changed to esc_attr() for the $name parameter since it's used within a URL attribute context. The fix adds esc_url() around the entire URL for proper escaping.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 2239
Old Code:
echo'<div class="notice notice-danger"><h2>Church Admin</h2><p>'.sprintf(__('You have permissions for %1$d out of %2$d modules','church-admin'),$permissions,$x).'</p>';

Fixed Code:
echo wp_kses_post('<div class="notice notice-danger"><h2>Church Admin</h2><p>'.sprintf(__('You have permissions for %1$d out of %2$d modules','church-admin'),$permissions,$x).'</p>');

Explanation:
The HTML structure with class attributes was being output without proper escaping. Although sprintf() with numeric placeholders is relatively safe, wp_kses_post() ensures all markup is properly sanitized.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 3250
Old Code:
window.location.href="'.admin_url().'admin.php?page=church_admin/index.php&action="+action;

Fixed Code:
window.location.href="'.esc_url(admin_url()).'admin.php?page=church_admin/index.php&action="+action;

Explanation:
The admin_url() output was not being escaped before being placed in a JavaScript string context. This could potentially allow for JavaScript injection if the URL contains malicious characters. The fix applies esc_url() to properly escape the URL for use in JavaScript.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 3304
Old Code:
echo'<form action="'.admin_url().'admin.php?page=church_admin/index.php#app" method="POST"><p><select name="app_page">';

Fixed Code:
echo'<form action="'.esc_url(admin_url().'admin.php?page=church_admin/index.php#app').'" method="POST"><p><select name="app_page">';

Explanation:
The admin_url() output was not being escaped before use in the form action attribute. The fix applies esc_url() to properly escape the URL for safe use in HTML attributes.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Lines 3356-3376
Old Code:
$out='
        <script type="text/javascript">
          google.charts.load("current", {"packages":["corechart"]});
          google.charts.setOnLoadCallback(drawChart);
          // ... chart code ...
        }</script>';
        $out.='<div id="app_graph" style="width:100%;height:200px;"></div>';
        echo $out;

Fixed Code:
echo esc_js('
        <script type="text/javascript">
          google.charts.load("current", {"packages":["corechart"]});
          google.charts.setOnLoadCallback(drawChart);
          // ... chart code ...
        }</script>');
        echo '<div id="app_graph" style="width:100%;height:200px;"></div>';

Explanation:
The JavaScript code was being output directly without proper escaping. The fix applies esc_js() to properly escape the JavaScript content for safe output in script tags. The code also removes unnecessary string concatenation.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Lines 3463, 3509, 3525, 3541
Old Code (multiple instances):
echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.admin_url().'admin.php?page=church_admin/index.php#support">Upgrade</a></p></div>';

Fixed Code:
echo'<div class="error"><p>'.esc_html( __("This feature is premium only",'church-admin' ) ).'<br><a class="button-primary" href="'.esc_url(admin_url().'admin.php?page=church_admin/index.php#support').'">Upgrade</a></p></div>';

Explanation:
Multiple instances throughout the file have URLs in href attributes that were not being escaped with esc_url(). This could allow for XSS attacks through malicious URL injection. The fixes apply esc_url() to properly escape the URLs.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php (Multiple instances)
Old Code (sample):
echo '<div class="notice notice-danger"><h2>'.esc_html( sprintf(__('You need "%1$s" permissions to access this page','church-admin' ) ,__('Directory','church-admin') )).'</h2></div>';

Fixed Code:
echo '<div class="notice notice-danger"><h2>';
echo esc_html(__('You need "Directory" permissions to access this page','church-admin'));
echo '</h2></div>';

Explanation:
Multiple instances throughout the file use sprintf() with string placeholders to build error messages. The original code attempts to escape the entire result, but the fix simplifies by directly using esc_html() on the translated string without sprintf(), making the escaping more explicit and reducing complexity. This is repeated approximately 50+ times in the diff.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 3476
Old Code:
echo church_admin_automations_list();

Fixed Code:
echo wp_kses_post(church_admin_automations_list());

Explanation:
The output from church_admin_automations_list() was not being escaped. Without knowing the function's implementation, the output could contain unescaped HTML that could be exploited for XSS. The fix applies wp_kses_post() to properly sanitize the output while allowing safe HTML.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 4089
Old Code:
echo church_admin_list_custom_fields();

Fixed Code:
church_admin_list_custom_fields();

Explanation:
The output from church_admin_list_custom_fields() was being echoed directly. The fix removes the echo statement, implying the function handles its own output directly or the output is not needed. This prevents potential XSS if the function returns unescaped content.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 4102
Old Code:
echo church_admin_edit_custom_field( $id);

Fixed Code:
church_admin_edit_custom_field( $id);

Explanation:
Similar to above, the echo statement is removed, implying the function handles its own output. This prevents potential XSS from function output.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 4112
Old Code:
echo church_admin_delete_custom_field( $id);

Fixed Code:
church_admin_delete_custom_field( $id);

Explanation:
Similar to above, the echo statement is removed to prevent XSS from unescaped function output.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 4125
Old Code:
echo church_admin_photo_list( $member_type_id);

Fixed Code:
echo wp_kses_post(church_admin_photo_list( $member_type_id) );

Explanation:
The output from church_admin_photo_list() was not being escaped. The fix applies wp_kses_post() to properly sanitize the output while allowing safe HTML.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 4138
Old Code:
echo church_admin_photo_permission_pdf_form();

Fixed Code:
echo wp_kses_post( church_admin_photo_permission_pdf_form() );

Explanation:
The output from church_admin_photo_permission_pdf_form() was not being escaped. The fix applies wp_kses_post() to properly sanitize the output.

---

Vulnerability Existed: yes
FALSE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 4168
Old Code:
echo church_admin_recent_people_activity();

Fixed Code:
church_admin_recent_people_activity();

Explanation:
The echo statement is removed, allowing the function to handle its own output or preventing XSS from unescaped output.

---

Vulnerability Existed: yes
TRUE POSITIVE
Improper Neutralization of Input During Web Page Generation - CWE-79 - includes/functions.php Line 4568
Old Code:
echo church_admin_merge_people( (int)$p1,(int)$p2 );

Fixed Code:
echo wp_kses_post(church_admin_merge_people( (int)$p1,(int)$p2 ) );

Explanation:
The output from church_admin_merge_people() was not being escaped. The fix applies wp_kses_post() to properly sanitize the HTML output while allowing safe markup.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/import.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/import.php	2026-01-18 00:19:18.195687646 +0000+++ cache/church-admin_5.0.29/includes/import.php	2026-01-18 00:24:12.561973182 +0000@@ -24,12 +24,12 @@             $wpdb->query('INSERT INTO '.$wpdb->prefix.'church_admin_household (address) VALUES("")');             $household_id=$wpdb->insert_id;             $people_id=$wpdb->query('INSERT INTO '.$wpdb->prefix.'church_admin_people (updated_by,people_type_id,head_of_household,member_type_id,user_id,household_id,show_me,gdpr_reason,first_name,last_name,email,first_registered) VALUES("'.$current_user->ID.'",1,1,1,"'.(int)$row->ID.'","'.(int)$household_id.'",0,"'.esc_sql(__('Imported from website user account')).'","'.esc_sql( $first_name).'","'.esc_sql( $last_name).'","'.esc_sql( $row->user_email).'","'.esc_sql(mysql2date('Y-m-d',$row->user_registered)).'")');-            //translators: %1$s is a user ID, 2,3,4 are parts of a  name+            /* translators: 1: is a user ID, 2:name part 3: name part 4:part of a name */             echo '<p>'.esc_html(sprintf(__('User %1$s: %2$s %3$s %4$s added.','church-admin' ) ,(int)$row->ID,esc_html( $first_name),esc_html( $last_name),esc_html( $row->user_email) ));         }         else         {-             //translators: %1$s is a user ID, 2,3  are  parts of a  name+             /* translators: 1: is a user ID, 2: name part 3: name part */             echo'<p>'.esc_html(sprintf(__('User %1$s: %2$s %3$s already in the directory','church-admin' ) ,(int)$row->ID, $first_name, $last_name)).'</p>';         }     }
AI Analysis
I'll analyze this code diff for security vulnerabilities.

Vulnerability Existed: no
[No CWE] - N/A - includes/import.php [27, 32]

Old Code:
```
//translators: %1$s is a user ID, 2,3,4 are parts of a  name
```
and
```
//translators: %1$s is a user ID, 2,3  are  parts of a  name
```

Fixed Code:
```
/* translators: 1: is a user ID, 2:name part 3: name part 4:part of a name */
```
and
```
/* translators: 1: is a user ID, 2: name part 3: name part */
```

Explanation:
This diff only contains changes to translator comments and their formatting. The changes convert single-line comments (`//`) to block comments (`/* */`) and update the translator documentation format. These are cosmetic/documentation changes that do not introduce, fix, or relate to any security vulnerabilities. The actual code logic, SQL queries, escaping functions (esc_sql, esc_html), and data handling remain completely unchanged. No security fixes or vulnerabilities are present in this diff.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/pdf_creator.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/pdf_creator.php	2026-01-18 00:19:18.195687646 +0000+++ cache/church-admin_5.0.29/includes/pdf_creator.php	2026-01-18 00:24:12.565973431 +0000@@ -513,7 +513,7 @@ 				$text=array(); 				foreach( $date_of_birth AS $name=>$dob) 				{-                    //translators: %1$s is name %2$s os a date+                    /* translators: 1: is name 2: date */ 					$content=strip_tags(sprintf(__('Date of birth for %1$s: %2$s','church-admin' ) ,$name,$doba0)); 					if( $dob!=end( $date_of_birth) ) 					$width=$pdf->GetStringWidth( $content);@@ -1377,11 +1377,11 @@         //Title         $pdf->AddPage('P',get_option('church_admin_pdf_size') );         $pdf->SetFont('DejaVu','B',16);-        //translators: %1$s is a title for the PDF+        /* translators: %s is a title for the PDF */         $PDFtitle = strip_tags( sprintf(__('Photo permission for %1$s','church-admin'),implode(', ',$title)));         $pdf->Cell(0,10,$PDFtitle,0,2,'C');         $pdf->SetFont('DejaVu','B',12);-        //translators: %1$s is a date+        /* translators: %s is a date */         $PDFdate = strip_tags( sprintf( __('Produced %1$s','church-admin'),wp_date(get_option('date_format'))));         $pdf->Cell(0,10,$PDFdate,0,2,'C');     if(!empty($results)){@@ -1392,7 +1392,7 @@             if($x>=5){                 $pdf->AddPage('P',get_option('church_admin_pdf_size') );                 $pdf->SetFont('DejaVu','B',16);-                //translators: %1$s is the title of the PDF+                /* translators: %s is the title of the PDF */                 $PDFtitle = strip_tags( sprintf(__('Photo permission for %1$s','church-admin'),implode(', ',$title)));                 $pdf->Cell(0,10,$PDFtitle,0,2,'C');                 $pdf->SetFont('DejaVu','B',12);@@ -1605,7 +1605,7 @@         //Title         $pdf->AddPage('P',get_option('church_admin_pdf_size') );         $pdf->SetFont('DejaVu','B',12);-        //translators: %1$s is  a date and %2$s is the facility name+        /* translators: 1: date and 2: is the facility name */         $PDFtitle = strip_tags( sprintf(__('Weekly Calendar w/c %1$s for %2$s','church-admin'),mysql2date(get_option('date_format'),$start_date),$what));         $pdf->Cell(0,10,$PDFtitle,0,2,'C');         $pdf->SetFont('DejaVu','B',12);@@ -1773,7 +1773,7 @@         }     }  -    //translators: %1$s is month, %2$s is year+    /* translators: 1: is month 2: is year */     $title = sprintf(__('Calendar %1$s %2$s','church-admin'), $monthname,$thisyear);  
AI Analysis
```
Vulnerability Existed: no
Not a Security Vulnerability - Code Comment Updates
File: includes/pdf_creator.php [Lines 516, 1380, 1384, 1395, 1608, 1776]

Old Code:
//translators: %1$s is name %2$s os a date
//translators: %1$s is a title for the PDF
//translators: %1$s is a date
//translators: %1$s is the title of the PDF
//translators: %1$s is  a date and %2$s is the facility name
//translators: %1$s is month, %2$s is year

Fixed Code:
/* translators: 1: is name 2: date */
/* translators: %s is a title for the PDF */
/* translators: %s is a date */
/* translators: %s is the title of the PDF */
/* translators: 1: date and 2: is the facility name */
/* translators: 1: is month 2: is year */

Explanation:
This diff contains only comment changes. The modifications update translator comments from single-line format (`//`) to multi-line format (`/* */`) and standardize the placeholder documentation syntax. These are purely stylistic improvements to code documentation and do not introduce or fix any security vulnerabilities. The actual code logic, variable handling, and sprintf() calls remain unchanged, so there is no security impact.
```
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/permissions.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/permissions.php	2026-01-18 00:19:18.195687646 +0000+++ cache/church-admin_5.0.29/includes/permissions.php	2026-01-18 00:24:12.569973679 +0000@@ -8,7 +8,7 @@ 	global $wpdb; 	if(!current_user_can('manage_options') ) 	{-		echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change options')).'</h2></div>';+		echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change options','church-admin')).'</h2></div>'; 		return; 	} 	$check=$wpdb->get_var('SELECT COUNT(user_id) FROM '.$wpdb->prefix.'church_admin_people');@@ -220,7 +220,7 @@ 			if ( empty( $user_permissions['Sessions'] ) ) $user_permissions['Sessions'] = ''; 			echo'<form action="admin.php?page=church_admin/index.php&section=settings&action=permissions" method="post">'; 			wp_nonce_field('permissions');-		//church_admin_autocomplete( $name='people',$first_id='friends',$second_id='to',$current_data=array(),$user_id=FALSE)+			//church_admin_autocomplete( $name='people',$first_id='friends',$second_id='to',$current_data=array(),$user_id=FALSE) 			echo'<table class="form-table"><tbody>'; 			echo'<tr><th scope="row" >'.esc_html( __('Delete All user permissions','church-admin' ) ).'</th><td><input type="checkbox" class="delete_all_permissions" value="yes" name="delete_all" />'.esc_html( __("Don't forget to save!",'church-admin' ) ).'</td></tr>'; 			echo'<tr><th scope="row" >'.esc_html( __('Attendance','church-admin' ) ).'</th><td>';
AI Analysis
Vulnerability Existed: no
[CWE Name] - [CWE ID] - includes/permissions.php [Lines 11]
[Old Code]
echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change options')).'</h2></div>';

[Fixed Code]
echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change options','church-admin')).'</h2></div>';

Explanation:
This change adds the domain parameter 'church-admin' to the WordPress `__()` translation function. This is not a security fix but rather an improvement to internationalization (i18n) compliance. The original code was already properly escaped with `esc_html()`, so there was no security vulnerability. The fix ensures the string is correctly attributed to the plugin's text domain for proper translation support.

---

Vulnerability Existed: no
[CWE Name] - [CWE ID] - includes/permissions.php [Lines 223]
[Old Code]
		//church_admin_autocomplete( $name='people',$first_id='friends',$second_id='to',$current_data=array(),$user_id=FALSE)

[Fixed Code]
			//church_admin_autocomplete( $name='people',$first_id='friends',$second_id='to',$current_data=array(),$user_id=FALSE)

Explanation:
This change only adjusts the indentation of a comment line (adding extra tabs for proper alignment). This is a code formatting change with no security implications. The comment remains inactive code and poses no security risk.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/podcast-settings.php AI: Not Sure 1 true positive
--- cache/church-admin_5.0.28/includes/podcast-settings.php	2026-01-18 00:19:18.195687646 +0000+++ cache/church-admin_5.0.29/includes/podcast-settings.php	2026-01-18 00:24:12.569973679 +0000@@ -20,7 +20,7 @@          global $wpdb,$church_admin_podcast_settings;     echo'<h2>'.esc_html( __('Podcast Settings for RSS file','church-admin' ) ).'</h2>';-    if(!empty( $settings )){echo'<p><a href="'.$url.'podcast.xml">Podcast RSS file</a></p>';}+    if(!empty( $settings )){echo'<p><a href="'.esc_url($url).'podcast.xml">Podcast RSS file</a></p>';}         $language_codes = array( 		'en-GB' => 'English UK' ,@@ -273,7 +273,7 @@                          update_option('church_admin_podcast_settings',$new_settings);             -            echo'<div class="notice notice-success inline"><p><strong>Podcast Settings Updated<br><a href="'.$url.'podcast.xml">Check Podcast RSS file</a></p></div>';+            echo'<div class="notice notice-success inline"><p><strong>Podcast Settings Updated<br><a href="'.esc_url($url).'podcast.xml">Check Podcast RSS file</a></p></div>';             require_once(plugin_dir_path(dirname(__FILE__) ).'includes/sermon-podcast.php');             church_admin_podcast_xml();             @@ -317,19 +317,19 @@             if(!empty( $settings['owner_email'] ) ) echo ' value="'.esc_html( $settings['owner_email'] ).'"';             echo '/></td></tr>';             echo'<tr><th scope="row">Language</th><td><select id="language" name="language">';-            $first=$option='';+                         foreach( $language_codes AS $key=>$value)             {-                if( $key==$settings['language'] )  {$first='<option value="'.esc_html( $key).'" selected="selected" >'.esc_html( $value).'</option>';}else{ $option.='<option value="'.esc_html( $key).'">'.esc_html( $value).'</option>';}+                echo '<option value="'.esc_html( $key).'" '.selected($key,$settings['language'],false).' >'.esc_html( $value).'</option>';             }-            echo $first.$option.'</select></td></tr>';+            echo '</select></td></tr>';             echo'<tr><th scope="row">Itunes Category</th><td><select id="category" name="category">';-            $first=$option='';+                         foreach( $cats AS $key=>$value)             {-                if( $value==$settings['category'] )  {$first='<option value="'.(int)$value.'" selected="selected" >'.esc_html( $value).'</option>';}else{ $option.='<option value="'.(int)$value.'">'.esc_html( $value).'</option>';}+                $first='<option value="'.(int)$value.'" '.selected($value,$settings['category'] ,false).' >'.esc_html( $value).'</option>';             }-            echo $first.$option.'</select></td></tr>';+            echo '</select></td></tr>';             echo'<tr><th scope="row">Image (1400px square)</th><td>';             echo'<input type="hidden" name="image_id" id="podcast_image_id" ';             if(!empty( $settings['image_id'] ) )echo' value="'.(int)$settings['image_id'].'" ';@@ -339,7 +339,9 @@                 $imagePath= wp_get_attachment_image_src( $settings['image_id'],'thumbnail');                 echo'<img src="'.$imagePath[0].'" id="podcast-image"><button id="remove-podcast-image"  class="button-secondary " >'.esc_html( __('Remove Image','church-admin' ) ).'</button>';             }-            elseif(!empty( $settings['image_path'] ) )  {echo'<img src="'.esc_url( $settings['image_path'] ).'" id="podcast-image"><button id="remove-podcast-image"  class="button-secondary " >'.esc_html( __('Remove Image','church-admin' ) ).'</button>';}+            elseif(!empty( $settings['image_path'] ) )  {+                echo'<img src="'.esc_url( $settings['image_path'] ).'" id="podcast-image"><button id="remove-podcast-image"  class="button-secondary " >'.esc_html( __('Remove Image','church-admin' ) ).'</button>';+            }             else{echo'<img src="https://dummyimage.com/300x300/000/fff&text=Podcast+Image" width="300" height="300" id="podcast-image" />';}                          echo'<button id="podcast-image-upload"  class="button-secondary " >'.esc_html( __('Upload Image','church-admin' ) ).'</button>';@@ -350,7 +352,9 @@             if(!empty( $settings['sermons'] ) )  {echo esc_html( $settings['sermons'] );}else{echo __('Sermons','church-admin');}             echo'"></td></tr>';             echo'<tr><th scope="row">'.esc_html( __('Series','church-admin' ) ).'</td><td><input type="text" name="series" value="';-            if(!empty( $settings['series'] ) )  {echo esc_html( $settings['series'] );}else{echo __('Series','church-admin');}+            if(!empty( $settings['series'] ) )  {+                echo esc_html( $settings['series'] );}else{echo esc_html(__('Series','church-admin'));+            }             echo'"></td></tr>';             echo'<tr><th scope="row">'.esc_html( __('Most popular','church-admin' ) ).'</td><td><input type="text" name="most-popular" value="';             if(!empty( $settings['most-popular'] ) )  {echo esc_html( $settings['most-popular'] );}else{echo __('Most popular','church-admin');}
AI Analysis
# Security Analysis of podcast-settings.php Diff

## Vulnerability 1

**Vulnerability Existed:** yes
TRUE POSITIVE

**Cross-site Scripting (XSS) - CWE-79 - includes/podcast-settings.php [23, 276]**

**Old Code:**
```php
echo'<p><a href="'.$url.'podcast.xml">Podcast RSS file</a></p>';
```
and
```php
echo'<div class="notice notice-success inline"><p><strong>Podcast Settings Updated<br><a href="'.$url.'podcast.xml">Check Podcast RSS file</a></p></div>';
```

**Fixed Code:**
```php
echo'<p><a href="'.esc_url($url).'podcast.xml">Podcast RSS file</a></p>';
```
and
```php
echo'<div class="notice notice-success inline"><p><strong>Podcast Settings Updated<br><a href="'.esc_url($url).'podcast.xml">Check Podcast RSS file</a></p></div>';
```

**Explanation:**
The `$url` variable was directly concatenated into an HTML href attribute without escaping. An attacker could inject malicious JavaScript via a crafted URL value (e.g., `javascript:alert('XSS')`). The fix applies `esc_url()`, which is the correct WordPress function to escape URLs for use in HTML attributes, preventing XSS attacks.

---

## Vulnerability 2

**Vulnerability Existed:** not sure

**Improper Output Encoding - CWE-116 - includes/podcast-settings.php [354-356]**

**Old Code:**
```php
if(!empty( $settings['series'] ) )  {echo esc_html( $settings['series'] );}else{echo __('Series','church-admin');}
```

**Fixed Code:**
```php
if(!empty( $settings['series'] ) )  {
    echo esc_html( $settings['series'] );}else{echo esc_html(__('Series','church-admin'));
}
```

**Explanation:**
The original code calls `__()` (translation function) without escaping its output when used in the else branch. While `__()` itself doesn't introduce XSS vulnerabilities with hardcoded strings, the fix adds `esc_html()` for consistency and defensive programming. This change ensures all echoed content is properly escaped regardless of translation source. This is a minor hardening measure rather than a critical vulnerability fix.

---

## Non-Vulnerability Changes

The remaining changes (lines 320, 327-328) refactor the select dropdown generation to use WordPress's `selected()` function instead of manual string concatenation. While these improve code quality and maintainability, they do not address new security vulnerabilities—the original approach was already safe since the keys and values were being escaped with `esc_html()`.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/sermon-podcast.php AI: 5 vulnerabilities 1 false positive, 4 true positives CVE-2026-0682
--- cache/church-admin_5.0.28/includes/sermon-podcast.php	2026-01-18 00:19:18.199687894 +0000+++ cache/church-admin_5.0.29/includes/sermon-podcast.php	2026-01-18 00:24:12.573973927 +0000@@ -693,6 +693,10 @@ 		             //from 3.6.20 use WordPress native function             $audiometadata=wp_read_audio_metadata( $path.$sanitizedFilename );+            if(empty($audiometadata)){+                echo'<div class="notice notice-danger">'.esc_html(__('File not recognised as an mp3','church-admin') ).'</div>';+                return;+            }             $length=!empty( $audiometadata['length_formatted'] )?$audiometadata['length_formatted']:null;  @@ -727,6 +731,7 @@         if(!empty( $_POST['private'] ) )  {$private="1";}else{$private="0";}          $servicesArray= get_option('church_admin_services');+        if(empty($servicesArray)){$servicesArray=array();}         if(!empty($form['service_name'])){             if(!in_array($form['service_name'],$servicesArray)){                 $servicesArray[]=$form['service_name'];@@ -1035,7 +1040,7 @@ 				case "lithuanian":   					$url='https://api.preachingcentral.com/bible.php?passage='.$passage.'&version='.$version; -  					$ch = curl_init( $url);+  					$ch = curl_init( esc_url($url));   					curl_setopt( $ch,CURLOPT_FAILONERROR,true);   					curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);   					$out='<p>';@@ -1169,21 +1174,17 @@         {             $errors['content']=__('You need to upload an audio file or enter an audio or video url','church-admin');         }-        /****************************************-         * Handle if Google share url in audio_url-         ***************************************/+                if(!empty( $form['audio_url'] ) )         {-            $sqlsafe['audio_url']=$form['audio_url'];+            $sqlsafe['audio_url']=esc_sql($form['audio_url']);             $audioURL=$form['audio_url'];-            church_admin_debug('URL: '.$sqlsafe['audio_url']);-           -            $mimeType=church_admin_getRemoteMimeType( $sqlsafe['audio_url'] );             -            $dot_and_ext = substr($sqlsafe['audio_url'] ,-4);-            church_admin_debug($dot_and_ext);+            $mimeType=church_admin_getRemoteMimeType( $sqlsafe['audio_url'] );//doesn't work for all servers+            +            $ext = substr($form['audio_url'],-4); -            if( $mimeType!='audio/mpeg' && $dot_and_ext!='.mp3' ) {$errors['audio_url']=__('External file is not an mp3','church-admin');}+            if( $mimeType!='audio/mpeg' && $ext!='.mp3')$errors['audio_url']=__('External file is not an mp3','church-admin');                          $length=!empty($form['external_duration'])?$form['external_duration']: NULL; @@ -1235,7 +1236,10 @@             $length=!empty( $audiometadata['length_formatted'] )?$audiometadata['length_formatted']:null; 		}         if(empty($file_name))$ile_name=null;+        +         $servicesArray= get_option('church_admin_services');+        if(empty($servicesArray)){$servicesArray=array();}         if(!empty($form['service_name'])){             if(!in_array($form['service_name'],$servicesArray)){                 $servicesArray[]=$form['service_name'];@@ -1244,13 +1248,17 @@             }          }+++             /******************************         *   Abort if there are errors         ******************************/         if(!empty( $errors) )  {             church_admin_debug("There were errors \r\n".print_r( $errors,TRUE) );-            echo wp_kses_post('<p>'.implode('<br>',$errors).'</p>');+            echo '<div class="notice notice-danger">'.wp_kses_post('<p>'.implode('<br>',$errors)).'</p></div>';             church_admin_sermon_form( $data,$errors);+            return;         }         else         {//save sermon@@ -1331,19 +1339,19 @@             if(empty($file_name)){$file_name=null;}              //church_admin_debug("SQLSAFE data\r\n".print_r( $sqlsafe,TRUE) );-            if ( empty( $file_id) )$file_id=$wpdb->get_var('SELECT file_id FROM '.$wpdb->prefix.'church_admin_sermon_files WHERE external_file="'.$sqlsafe['audio_url'].'" AND length="'.$length.'" AND private="'.$private.'" AND file_name="'.$file_name.'" AND file_title="'.$sqlsafe['file_title'].'" AND file_description="'.$sqlsafe['file_description'].'" AND service_id="'.$sqlsafe['service_id'].'" AND series_id="'.$sqlsafe['series_id'].'" AND speaker="'.$speaker.'"');+            if ( empty( $file_id) )$file_id=$wpdb->get_var('SELECT file_id FROM '.$wpdb->prefix.'church_admin_sermon_files WHERE external_file="'.esc_sql($form['audio_url']).'" AND length="'.$length.'" AND private="'.$private.'" AND file_name="'.$file_name.'" AND file_title="'.$sqlsafe['file_title'].'" AND file_description="'.$sqlsafe['file_description'].'" AND service_id="'.$sqlsafe['service_id'].'" AND series_id="'.$sqlsafe['series_id'].'" AND speaker="'.$speaker.'"');             //church_admin_debug( $wpdb->last_query);             if(!empty( $file_id) )             {//update                 -                $sql='UPDATE '.$wpdb->prefix.'church_admin_sermon_files SET embed_code="'.esc_sql( $embed_code ).'",external_file="'.$sqlsafe['audio_url'].'", video_url="'.$sqlsafe['video_url'].'",transcript="'.$transcript.'",file_subtitle="'.$sqlsafe['file_subtitle'].'",pub_date="'.$sqlsafe['pub_date'].'",length="'.$length.'", private="'.$private.'",last_modified="'.date("Y-m-d H:i:s" ).'",file_name="'.esc_sql($file_name).'" , file_title="'.$sqlsafe['file_title'].'" , file_description="'.$sqlsafe['file_description'].'" , service_id="'.$sqlsafe['service_id'].'",series_id="'.$sqlsafe['series_id'].'" , speaker="'.$speaker.'", bible_passages="'.$passages.'",bible_texts="'.$sqlsafe['passages'].'",file_slug="'.esc_sql(sanitize_title( $form['file_title'] ) ).'" WHERE file_id="'.esc_sql( $file_id).'"';+                $sql='UPDATE '.$wpdb->prefix.'church_admin_sermon_files SET embed_code="'.esc_sql( $embed_code ).'",external_file="'.esc_sql($form['audio_url']).'", video_url="'.esc_sql($form['video_url']).'",transcript="'.$transcript.'",file_subtitle="'.$sqlsafe['file_subtitle'].'",pub_date="'.$sqlsafe['pub_date'].'",length="'.$length.'", private="'.$private.'",last_modified="'.date("Y-m-d H:i:s" ).'",file_name="'.esc_sql($file_name).'" , file_title="'.$sqlsafe['file_title'].'" , file_description="'.$sqlsafe['file_description'].'" , service_id="'.$sqlsafe['service_id'].'",series_id="'.$sqlsafe['series_id'].'" , speaker="'.$speaker.'", bible_passages="'.$passages.'",bible_texts="'.$sqlsafe['passages'].'",file_slug="'.esc_sql(sanitize_title( $form['file_title'] ) ).'" WHERE file_id="'.esc_sql( $file_id).'"';                  $wpdb->query( $sql);                 //church_admin_debug("DB Update \r\n".$wpdb->last_query);             }//end update             else             {//insert-                $sql='INSERT INTO '.$wpdb->prefix.'church_admin_sermon_files (file_name,file_title,file_subtitle,file_description,private,length,service_id,series_id,speaker,pub_date,last_modified,transcript,video_url,external_file,bible_passages,bible_texts,file_slug,embed_code)VALUES("'.esc_sql($file_name).'","'.$sqlsafe['file_title'].'","'.$sqlsafe['file_subtitle'].'","'.$sqlsafe['file_description'].'" ,"'.$private.'","'.$length.'","'.$sqlsafe['service_id'].'","'.$sqlsafe['series_id'].'","'.$speaker.'" ,"'.$sqlsafe['pub_date'].'","'.date("Y-m-d H:i:s" ).'","'.$transcript.'","'.$sqlsafe['video_url'].'","'.$sqlsafe['audio_url'].'","'.$passages.'","'.$sqlsafe['passages'].'","'.esc_sql(sanitize_title( $form['file_title'] ) ).'","'.esc_sql( $embed_code ).'")';+                $sql='INSERT INTO '.$wpdb->prefix.'church_admin_sermon_files (file_name,file_title,file_subtitle,file_description,private,length,service_id,series_id,speaker,pub_date,last_modified,transcript,video_url,external_file,bible_passages,bible_texts,file_slug,embed_code)VALUES("'.esc_sql($file_name).'","'.$sqlsafe['file_title'].'","'.$sqlsafe['file_subtitle'].'","'.$sqlsafe['file_description'].'" ,"'.$private.'","'.$length.'","'.$sqlsafe['service_id'].'","'.$sqlsafe['series_id'].'","'.$speaker.'" ,"'.$sqlsafe['pub_date'].'","'.date("Y-m-d H:i:s" ).'","'.$transcript.'","'.esc_sql($sqlsafe['video_url']).'","'.esc_sql($form['audio_url']).'","'.$passages.'","'.$sqlsafe['passages'].'","'.esc_sql(sanitize_title( $form['file_title'] ) ).'","'.esc_sql( $embed_code ).'")';                 $wpdb->query( $sql);                 //church_admin_debug("DB Insert \r\n".$wpdb->last_query);                 $file_id=$wpdb->insert_id;
AI Analysis
I'll analyze this code diff for security vulnerabilities following the specified format.

---

**Vulnerability 1:**

Vulnerability Existed: yes
FALSE POSITIVE

**SQL Injection - CWE-89** - includes/sermon-podcast.php Lines 1176, 1179

Old Code:
```php
$sqlsafe['audio_url']=$form['audio_url'];
$audioURL=$form['audio_url'];
church_admin_debug('URL: '.$sqlsafe['audio_url']);

$mimeType=church_admin_getRemoteMimeType( $sqlsafe['audio_url'] );

$dot_and_ext = substr($sqlsafe['audio_url'] ,-4);
```

Fixed Code:
```php
$sqlsafe['audio_url']=esc_sql($form['audio_url']);
$audioURL=$form['audio_url'];

$mimeType=church_admin_getRemoteMimeType( $sqlsafe['audio_url'] );//doesn't work for all servers

$ext = substr($form['audio_url'],-4);
```

Explanation:
The original code used unsanitized user input (`$form['audio_url']`) directly in SQL queries without escaping. The fix applies `esc_sql()` to sanitize the audio URL before database operations, preventing SQL injection attacks where malicious SQL could be injected through the audio_url parameter.

---

**Vulnerability 2:**

Vulnerability Existed: yes
TRUE POSITIVE

**SQL Injection - CWE-89** - includes/sermon-podcast.php Line 1342

Old Code:
```php
if ( empty( $file_id) )$file_id=$wpdb->get_var('SELECT file_id FROM '.$wpdb->prefix.'church_admin_sermon_files WHERE external_file="'.$sqlsafe['audio_url'].'" AND length="'.$length.'" AND private="'.$private.'" AND file_name="'.$file_name.'" AND file_title="'.$sqlsafe['file_title'].'" AND file_description="'.$sqlsafe['file_description'].'" AND service_id="'.$sqlsafe['service_id'].'" AND series_id="'.$sqlsafe['series_id'].'" AND speaker="'.$speaker.'"');
```

Fixed Code:
```php
if ( empty( $file_id) )$file_id=$wpdb->get_var('SELECT file_id FROM '.$wpdb->prefix.'church_admin_sermon_files WHERE external_file="'.esc_sql($form['audio_url']).'" AND length="'.$length.'" AND private="'.$private.'" AND file_name="'.$file_name.'" AND file_title="'.$sqlsafe['file_title'].'" AND file_description="'.$sqlsafe['file_description'].'" AND service_id="'.$sqlsafe['service_id'].'" AND series_id="'.$sqlsafe['series_id'].'" AND speaker="'.$speaker.'"');
```

Explanation:
The SELECT query used unsanitized `$sqlsafe['audio_url']` (which was not escaped in the original code). The fix applies `esc_sql()` to the source data (`$form['audio_url']`) in the WHERE clause, preventing SQL injection through this query parameter.

---

**Vulnerability 3:**

Vulnerability Existed: yes
TRUE POSITIVE

**SQL Injection - CWE-89** - includes/sermon-podcast.php Line 1350

Old Code:
```php
$sql='UPDATE '.$wpdb->prefix.'church_admin_sermon_files SET embed_code="'.esc_sql( $embed_code ).'",external_file="'.$sqlsafe['audio_url'].'", video_url="'.$sqlsafe['video_url'].'",transcript="'.$transcript.'",file_subtitle="'.$sqlsafe['file_subtitle'].'",pub_date="'.$sqlsafe['pub_date'].'",length="'.$length.'", private="'.$private.'",last_modified="'.date("Y-m-d H:i:s" ).'",file_name="'.esc_sql($file_name).'" , file_title="'.$sqlsafe['file_title'].'" , file_description="'.$sqlsafe['file_description'].'" , service_id="'.$sqlsafe['service_id'].'",series_id="'.$sqlsafe['series_id'].'" , speaker="'.$speaker.'", bible_passages="'.$passages.'",bible_texts="'.$sqlsafe['passages'].'",file_slug="'.esc_sql(sanitize_title( $form['file_title'] ) ).'" WHERE file_id="'.esc_sql( $file_id).'"';
```

Fixed Code:
```php
$sql='UPDATE '.$wpdb->prefix.'church_admin_sermon_files SET embed_code="'.esc_sql( $embed_code ).'",external_file="'.esc_sql($form['audio_url']).'", video_url="'.esc_sql($form['video_url']).'",transcript="'.$transcript.'",file_subtitle="'.$sqlsafe['file_subtitle'].'",pub_date="'.$sqlsafe['pub_date'].'",length="'.$length.'", private="'.$private.'",last_modified="'.date("Y-m-d H:i:s" ).'",file_name="'.esc_sql($file_name).'" , file_title="'.$sqlsafe['file_title'].'" , file_description="'.$sqlsafe['file_description'].'" , service_id="'.$sqlsafe['service_id'].'",series_id="'.$sqlsafe['series_id'].'" , speaker="'.$speaker.'", bible_passages="'.$passages.'",bible_texts="'.$sqlsafe['passages'].'",file_slug="'.esc_sql(sanitize_title( $form['file_title'] ) ).'" WHERE file_id="'.esc_sql( $file_id).'"';
```

Explanation:
The UPDATE query contained unescaped values `$sqlsafe['audio_url']` and `$sqlsafe['video_url']`. The fix applies `esc_sql()` directly to the form input data (`$form['audio_url']` and `$form['video_url']`), preventing SQL injection through these fields in the UPDATE statement.

---

**Vulnerability 4:**

Vulnerability Existed: yes
TRUE POSITIVE

**SQL Injection - CWE-89** - includes/sermon-podcast.php Line 1357

Old Code:
```php
$sql='INSERT INTO '.$wpdb->prefix.'church_admin_sermon_files (file_name,file_title,file_subtitle,file_description,private,length,service_id,series_id,speaker,pub_date,last_modified,transcript,video_url,external_file,bible_passages,bible_texts,file_slug,embed_code)VALUES("'.esc_sql($file_name).'","'.$sqlsafe['file_title'].'","'.$sqlsafe['file_subtitle'].'","'.$sqlsafe['file_description'].'" ,"'.$private.'","'.$length.'","'.$sqlsafe['service_id'].'","'.$sqlsafe['series_id'].'","'.$speaker.'" ,"'.$sqlsafe['pub_date'].'","'.date("Y-m-d H:i:s" ).'","'.$transcript.'","'.$sqlsafe['video_url'].'","'.$sqlsafe['audio_url'].'","'.$passages.'","'.$sqlsafe['passages'].'","'.esc_sql(sanitize_title( $form['file_title'] ) ).'","'.esc_sql( $embed_code ).'")';
```

Fixed Code:
```php
$sql='INSERT INTO '.$wpdb->prefix.'church_admin_sermon_files (file_name,file_title,file_subtitle,file_description,private,length,service_id,series_id,speaker,pub_date,last_modified,transcript,video_url,external_file,bible_passages,bible_texts,file_slug,embed_code)VALUES("'.esc_sql($file_name).'","'.$sqlsafe['file_title'].'","'.$sqlsafe['file_subtitle'].'","'.$sqlsafe['file_description'].'" ,"'.$private.'","'.$length.'","'.$sqlsafe['service_id'].'","'.$sqlsafe['series_id'].'","'.$speaker.'" ,"'.$sqlsafe['pub_date'].'","'.date("Y-m-d H:i:s" ).'","'.$transcript.'","'.esc_sql($sqlsafe['video_url']).'","'.esc_sql($form['audio_url']).'","'.$passages.'","'.$sqlsafe['passages'].'","'.esc_sql(sanitize_title( $form['file_title'] ) ).'","'.esc_sql( $embed_code ).'")';
```

Explanation:
The INSERT query had unescaped `$sqlsafe['video_url']` and `$sqlsafe['audio_url']` values. The fix applies `esc_sql()` to properly escape these fields before insertion, preventing SQL injection vulnerabilities in the INSERT statement.

---

**Vulnerability 5:**

Vulnerability Existed: yes
TRUE POSITIVE

**Improper URL Validation - CWE-95/CWE-601** - includes/sermon-podcast.php Line 1043

Old Code:
```php
$ch = curl_init( $url);
```

Fixed Code:
```php
$ch = curl_init( esc_url($url));
```

Explanation:
The curl_init function received an unvalidated URL that could contain malicious code or protocols. The fix applies `esc_url()` to sanitize and validate the URL before passing it to curl_init, preventing potential code injection or SSRF (Server-Side Request Forgery) attacks through malicious URL schemes.
CVE Analysis Results:
CVE-2026-0682: Yes
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/settings.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/settings.php	2026-01-18 00:19:18.199687894 +0000+++ cache/church-admin_5.0.29/includes/settings.php	2026-01-18 00:24:12.573973927 +0000@@ -26,7 +26,7 @@ 		}  		update_option('church_admin_modules',$modules);-        echo '<div class="notice notice-success inline"><h2>'.esc_html( __('Modules updated - refresh page to show changes in menu')).'</h2></div>';+        echo '<div class="notice notice-success inline"><h2>'.esc_html( __('Modules updated - refresh page to show changes in menu','church-admin')).'</h2></div>'; 	}  		echo'<h1 class="modules">'.esc_html( __('Set which module tabs are visible ','church-admin' ) ).'</h2>';@@ -335,7 +335,7 @@ 	echo'<div class="church-admin-form-group"><input type="radio" class="speed" id="immediate"  name="cron" value="immediate" '.checked( $current_cron,'immediate',false).'/><label>'.esc_html( __('Send Emails Immediately','church-admin' ) ).' ('.esc_html( __("Use this option if your hosting company doesn't limit how many emails you can send an hour",'church-admin' ) ).')</label></div>'; 	echo'<div class="church-admin-form-group"><input type="radio"  class="speed cron" name="cron" value="cron" '.checked( $current_cron,'cron',false).'/><label>'.esc_html( __('I want to use cron','church-admin' ) ).' ('.esc_html( __('Use this option if you are on a Linux server and are limited how many emails you can send an hour','church-admin' ) ).')</label></div>'; 	$cronCommand='<strong>curl --silent '.admin_url().'/admin-ajax.php?action=church_admin_cronemail</strong>';-	//translators: %1$s is a cron command+	/* translators: 1: is a cron command */ 	echo'<p>'.wp_kses_post(sprintf(__('Set up a cron job with the command %1$s in your cPanel or hosting account','church-admin' ) ,$cronCommand)).'</p>'; 	echo'<div class="church-admin-form-group"><input  id="wp-cron" type="radio" class="speed wp-cron" name="cron" value="wp-cron" '.checked( $current_cron,'wp-cron',FALSE).'/><label>'.esc_html( __('I want to use wp-cron','church-admin' ) ).' ('.esc_html( __("Use this option if you are on a Windows server or don't understand cron and are limited how many emails you can send an hour. It will be set to send a batch every hour.",'church-admin' ) ).')</label></div>'; 	echo '<div id="batch-size" ';@@ -1095,13 +1095,13 @@ 	if(file_exists( $debug_path) ) 	{ 		$filesize=filesize( $debug_path);-		//translators: %1$s is a file path+		/* translators: %s is a file path */ 		echo'<p>'.esc_html(sprintf(__('Debug path: %1$s','church-admin'),$debug_path)).'</p>'; 		echo'<p><a class="button-secondary" href="'.wp_nonce_url('admin.php?page=church_admin/index.php&amp;section=settings&action=clear-debug','clear-debug').'">'.esc_html( __('Clear Debug Log','church-admin' ) ).'</a></p>'; 	 		$filesize=filesize( $debug_path); 		$size=size_format( $filesize, $decimals = 2 );-		//translators: %1$s is file size+		/* translators: %s is a file size */ 		echo'<p>'.esc_html(sprintf(__('Debug file is currently %1$s','church-admin' ) ,$size)).'</p>'; 	 		if( $filesize<2097152)@@ -1136,7 +1136,7 @@ 	$filesize=@filesize( $debug_path); 	$size=size_format( $filesize, $decimals = 2 ); 	echo'<h2>'.esc_html( __("Send debug log to support",'church-admin' ) ).'</h2>';-	//translators: %1$s is a file size+	/* translators: %s is a file size */ 	echo'<p>'.esc_html(sprintf(__('Debug file is currently %1$s','church-admin' ) ,$size)).'</p>'; 	if( $filesize>2097152)  {echo '<p>'.esc_html( __("Debug log is too big",'church-admin' ) ).'</p>';return;} 	if( $filesize<500)  {echo '<p>'.esc_html( __("Debug log is too small to send (not enough debug data). Please repeat the task you are wanting to report a bug for and refresh this page.",'church-admin' ) ).'</p>';return;}@@ -1200,7 +1200,7 @@ 	echo'<p style="color:red">'.esc_html( __('Use with caution as overrides individuals settings','church-admin' ) ).'</p>'; 	if(!current_user_can('manage_options') ) 	{-		echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change global email settings')).'</h2></div>';+		echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change global email settings','church-admin')).'</h2></div>'; 		return; 	} 	$results=$wpdb->get_results('SELECT people_id FROM '.$wpdb->prefix.'church_admin_people WHERE email IS NOT NULL AND gdpr_reason IS NOT NULL');
AI Analysis
# Security Analysis - PatchLeaks Code Diff

---

**Vulnerability 1:**

Vulnerability Existed: **no**

Improper Internationalization - Missing Text Domain - Line 29
- **Old Code:**
  ```php
  echo '<div class="notice notice-success inline"><h2>'.esc_html( __('Modules updated - refresh page to show changes in menu')).'</h2></div>';
  ```
- **Fixed Code:**
  ```php
  echo '<div class="notice notice-success inline"><h2>'.esc_html( __('Modules updated - refresh page to show changes in menu','church-admin')).'</h2></div>';
  ```
- **Explanation:**
  This is not a security vulnerability but a localization best practice fix. The change adds the text domain `'church-admin'` as the second parameter to the `__()` function. While this improves internationalization support, it does not represent a security fix for an existing vulnerability. The code was already properly escaped with `esc_html()`.

---

**Vulnerability 2:**

Vulnerability Existed: **no**

Improper Internationalization - Translator Comment Format - Lines 338, 1098, 1103, 1139, 1203
- **Old Code:**
  ```php
  //translators: %1$s is a cron command
  //translators: %1$s is a file path
  //translators: %1$s is file size
  //translators: %1$s is a file size
  ```
- **Fixed Code:**
  ```php
  /* translators: 1: is a cron command */
  /* translators: %s is a file path */
  /* translators: %s is a file size */
  /* translators: %s is a file size */
  ```
- **Explanation:**
  These are comment format corrections for WordPress translator comments. The changes standardize the comment format from single-line `//` comments to block comments `/* */` and update placeholder references from `%1$s` to `%s` or the proper format. This is a code quality/localization improvement, not a security vulnerability fix. The underlying code remains secure with proper use of `esc_html()` and `wp_kses_post()`.

---

**Vulnerability 3:**

Vulnerability Existed: **no**

Improper Internationalization - Missing Text Domain - Line 1203
- **Old Code:**
  ```php
  echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change global email settings')).'</h2></div>';
  ```
- **Fixed Code:**
  ```php
  echo '<div class="notice notice-danger"><h2>'.esc_html( __('Only site administrators can change global email settings','church-admin')).'</h2></div>';
  ```
- **Explanation:**
  Like Vulnerability 1, this is a localization improvement adding the text domain parameter to the `__()` function. No security vulnerability exists here; the output is properly escaped with `esc_html()`.

---

## Summary

This diff contains **no security fixes** for actual vulnerabilities. All changes are **localization and code quality improvements**:
- Adding missing text domain parameters to translation functions
- Standardizing translator comment formatting
- All output is properly escaped (no XSS risks)

The code was already secure in the previous version.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
includes/shortcode-generator.php AI: No vulnerabilities
--- cache/church-admin_5.0.28/includes/shortcode-generator.php	2026-01-18 00:19:18.199687894 +0000+++ cache/church-admin_5.0.29/includes/shortcode-generator.php	2026-01-18 00:24:12.573973927 +0000@@ -458,7 +458,7 @@     }     else{         $js=$description='';-        //translators: %1$s is a number+        /* translators: %s is an number */         $out.='<p><strong>'.esc_html( sprintf( __( 'There are %1$s shortcodes to choose from. Some will display a list of various optional options.','church-admin' ) ,count($shortcodes))).'</strong></p>'."\r\n";         $out.='<form action="" method="POST">'."\r\n";         $out.='<div ><label>'.esc_html( __('Choose shortcode','church-admin' ) ).'</label>'."\r\n";@@ -689,8 +689,8 @@         }         //style         $out.='<div class="church-admin-form-group shortcode-option" id="style" ><h3>'.esc_html( __('Calendar Style','church-admin' ) ).'</h3>';-        $out.='<p><input type="radio"  name="style" value="table" /><label> '.esc_html(__('Table Style') ).'</label></p>';-        $out.='<p><input type="radio"  name="style" checked="checked" value="new" /><label> '.esc_html(__('New Style') ).'</label></p>';+        $out.='<p><input type="radio"  name="style" value="table" /><label> '.esc_html(__('Table Style','church-admin') ).'</label></p>';+        $out.='<p><input type="radio"  name="style" checked="checked" value="new" /><label> '.esc_html(__('New Style','church-admin') ).'</label></p>';         $out.='</div>'."\r\n";         //show age         $out.='<div class="church-admin-form-group shortcode-option" id="show_age" ><h3>'.esc_html( __('Show age','church-admin' ) ).'</h3>';
AI Analysis
I'll analyze this code diff for security vulnerabilities.

---

**Vulnerability 1:**

Vulnerability Existed: no

Improper Neutralization of Input During Web Page Generation - CWE-79 (XSS) - includes/shortcode-generator.php - Lines 692-693

**Old Code:**
```php
$out.='<p><input type="radio"  name="style" value="table" /><label> '.esc_html(__('Table Style') ).'</label></p>';
$out.='<p><input type="radio"  name="style" checked="checked" value="new" /><label> '.esc_html(__('New Style') ).'</label></p>';
```

**Fixed Code:**
```php
$out.='<p><input type="radio"  name="style" value="table" /><label> '.esc_html(__('Table Style','church-admin') ).'</label></p>';
$out.='<p><input type="radio"  name="style" checked="checked" value="new" /><label> '.esc_html(__('New Style','church-admin') ).'</label></p>';
```

Explanation:
This is NOT a security fix, but rather a code quality improvement. The change adds the text domain parameter `'church-admin'` to the `__()` translation functions. This is a WordPress best practice for internationalization (i18n) to ensure proper translation handling. The code already uses `esc_html()` for output escaping, which prevents XSS vulnerabilities. Adding the text domain parameter doesn't address a security vulnerability but rather improves the code's adherence to WordPress standards.

---

**Vulnerability 2:**

Vulnerability Existed: no

No Security Vulnerability - includes/shortcode-generator.php - Line 461

**Old Code:**
```php
//translators: %1$s is a number
```

**Fixed Code:**
```php
/* translators: %s is an number */
```

Explanation:
This change is merely a comment style update and correction of the placeholder notation. It does not address any security vulnerability. The old code used a single-line comment format and referenced `%1$s`, while the fixed code uses a multi-line comment format and references `%s`. This is a documentation/translation comment update with no security implications.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.
premium-installer.php AI: 2 vulnerabilities 1 false positive, 1 true positive
--- cache/church-admin_5.0.28/premium-installer.php	2026-01-18 00:19:18.199687894 +0000+++ cache/church-admin_5.0.29/premium-installer.php	2026-01-18 00:24:12.573973927 +0000@@ -22,14 +22,16 @@ 		$result = church_admin_install_plugin( $plugin_info );  		if ( $result['success'] ) {-			echo '<div class="notice notice-success"><h2>'.__('Success','church-admin').'</h2><p>' . esc_html($result['message']).'</p>';+			echo '<div class="notice notice-success"><h2>';+			echo esc_html(__('Success','church-admin') );+			echo '</h2><p>' . esc_html($result['message']).'</p>';             echo'<p>'.esc_html(__('You have  installed & activated the premium version. Please deactivate this free version of "Church Admin" to use the premium version.','church-admin') ).'</p>';             echo'<p><a class="button-primary" href="'.esc_url(wp_nonce_url(admin_url().'plugins.php?action=deactivate&plugin=church-admin/church-admin.php','deactivate-plugin_church-admin/church-admin.php')).'">'.esc_html(__('Deactivate now','church-admin')).'</a></p>';                 echo '</div>';                          		} else {-			echo '<div class="notice notice-warning"><h2>'.__('Error','church-admin').'</h2><p>' . esc_html($result['message']).'</p></div>';+			echo '<div class="notice notice-warning"><h2>'.esc_html( __('Error','church-admin') ).'</h2><p>' . esc_html($result['message']).'</p></div>'; 		} 	} 	exit;
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - premium-installer.php [Line 25]

Old Code:
```
echo '<div class="notice notice-success"><h2>'.__('Success','church-admin').'</h2><p>' . esc_html($result['message']).'</p>';
```

Fixed Code:
```
echo '<div class="notice notice-success"><h2>';
echo esc_html(__('Success','church-admin') );
echo '</h2><p>' . esc_html($result['message']).'</p>';
```

Explanation:
The old code concatenated the output of `__('Success','church-admin')` directly into the HTML without escaping. The `__()` function performs translation but does NOT escape HTML entities. If the translation string contained user-controlled data or was compromised, it could inject arbitrary HTML/JavaScript. The fix properly escapes the translated string using `esc_html()` before output, preventing XSS attacks.

---

Vulnerability Existed: yes
FALSE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - premium-installer.php [Line 32]

Old Code:
```
echo '<div class="notice notice-warning"><h2>'.__('Error','church-admin').'</h2><p>' . esc_html($result['message']).'</p></div>';
```

Fixed Code:
```
echo '<div class="notice notice-warning"><h2>'.esc_html( __('Error','church-admin') ).'</h2><p>' . esc_html($result['message']).'</p></div>';
```

Explanation:
Same vulnerability as above. The `__('Error','church-admin')` output was concatenated directly without escaping. The fix wraps it with `esc_html()` to properly escape the translated string before output, preventing potential XSS injection through compromised or malicious translation strings.
CVE Analysis Results:
CVE-2026-0682: No
View CVE Description
The Church Admin plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.0.28 due to insufficient validation of user-supplied URLs in the 'audio_url' parameter. This makes it possible for authenticated attackers, with Administrator-level access, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.