CVE-2024-1109 (published 2024-02-07T11:15Z)

The Podlove Podcast Publisher plugin for WordPress is vulnerable to unauthorized access of data due to a missing capability check on the init_download() and init() functions in all versions up to, and including, 4.0.11. This makes it possible for unauthenticated attackers to export the plugin's tracking data and podcast information.

CVSS v3 base score: 5.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-862
cwe_name: Missing Authorization
description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are not applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/podlove/podlove-publisher
commit_details: repo_url: https://github.com/podlove/podlove-publisher
author: Eric Teubert
author_date: 2024-02-04 21:15:41+01:00
msg: fix: add missing capability check and nonce validation to exporter functions
repository: repo_url: https://github.com/podlove/podlove-publisher
repo_name: podlove/podlove-publisher
description: Podlove Podcast Publisher for WordPress
repo_language: PHP
owner: podlove
file_changes: filename: podcast_exporter.php
change_type: ModificationType.MODIFY
diff: @@ -30,6 +30,14 @@ class PodcastExporter
         }
 
         if (isset($_GET['podlove_export']) && $_GET['podlove_export']) {
+            if (!current_user_can('administrator')) {
+                return;
+            }
+
+            if (!wp_verify_nonce($_REQUEST['_podlove_nonce'], 'podlove_export')) {
+                return;
+            }
+
             $exporter = new \Podlove\Modules\ImportExport\Export\PodcastExporter();
             $exporter->download();
             exit;

programming_language: PHP
filename: tracking_exporter.php
change_type: ModificationType.MODIFY
diff: @@ -19,6 +19,14 @@ class TrackingExporter
         }
 
         if (isset($_GET['podlove_export_tracking']) && $_GET['podlove_export_tracking']) {
+            if (!current_user_can('administrator')) {
+                exit;
+            }
+
+            if (!wp_verify_nonce($_REQUEST['_podlove_nonce'], 'podlove_export_tracking_download')) {
+                exit;
+            }
+
             delete_transient('podlove_tracking_export_finished');
 
             header('Content-Type: application/octet-stream');
@@ -43,9 +51,17 @@ class TrackingExporter
     {
         global $wpdb;
 
+        if (!current_user_can('administrator')) {
+            exit;
+        }
+
+        if (!wp_verify_nonce($_REQUEST['_podlove_nonce'], 'podlove_export_tracking')) {
+            exit;
+        }
+
         // only one export at a time
         if (get_option('podlove_tracking_export_all') !== false) {
-            return;
+            exit;
         }
 
         update_option('podlove_tracking_export_all', $wpdb->get_var('SELECT COUNT(*) FROM '.\Podlove\Model\DownloadIntent::table_name()));

programming_language: PHP
filename: import_export.php
change_type: ModificationType.MODIFY
diff: @@ -123,7 +123,7 @@ class Import_Export extends \Podlove\Modules\Base
 			<li><?php echo __('In your new WordPress instance, import that file.', 'podlove-podcasting-plugin-for-wordpress'); ?></li>
 		</ol>
 
-		<a href="?podlove_export=1" class="button"><?php echo __('Export Podcast Data', 'podlove-podcasting-plugin-for-wordpress'); ?></a>
+		<a href="?podlove_export=1&_podlove_nonce=<?php echo wp_create_nonce('podlove_export'); ?>" class="button"><?php echo __('Export Podcast Data', 'podlove-podcasting-plugin-for-wordpress'); ?></a>
 		<?php
     }
 
@@ -168,12 +168,12 @@ class Import_Export extends \Podlove\Modules\Base
 							$("#podlove_tracking_export_status_wrapper").show();
 
 							timeoutID = window.setTimeout(podlove_check_export_status, 1000);
-						} 
+						}
 
 						if (result.finished) {
 							$("#podlove_tracking_export").attr('disabled', false);
 							$("#podlove_tracking_export_status_wrapper").hide();
-							window.location = window.location + "&podlove_export_tracking=1";
+							window.location = window.location + "&podlove_export_tracking=1&_podlove_nonce=<?php echo wp_create_nonce('podlove_export_tracking_download'); ?>";
 						}
 					}
 				});
@@ -187,20 +187,19 @@ class Import_Export extends \Podlove\Modules\Base
 
 				$.ajax({
 					url: ajaxurl,
-					data: {action: 'podlove-export-tracking'},
-					dataType: 'json',
-					success: function(result) {
+					data: {action: 'podlove-export-tracking', _podlove_nonce: '<?php echo wp_create_nonce('podlove_export_tracking'); ?>'},
+					dataType: 'json'
+				}).done(function(result) {
 						console.log("tracking export finished");
-					}
+				    window.setTimeout(podlove_check_export_status, 2000);
 				});
 
-				window.setTimeout(podlove_check_export_status, 2000);
 			});
 
 			// start immediately, in case the user refreshes the page
 			podlove_check_export_status();
 		}(jQuery));
-		</script>		
+		</script>
 		<?php
     }
 
@@ -213,10 +212,10 @@ class Import_Export extends \Podlove\Modules\Base
 
 		<form method="POST" enctype="multipart/form-data">
 			(<span><?php echo self::get_maximum_upload_size_text(); ?></span>)
-			<input type="file" name="podlove_import"/> 
+			<input type="file" name="podlove_import"/>
 			<input type="submit" value="<?php echo __('Import Podcast Data', 'podlove-podcasting-plugin-for-wordpress'); ?>" class="button" />
 			<?php wp_nonce_field('podlove_import', '_podlove_nonce'); ?>
-		</form>		
+		</form>
 		<?php
     }
 
@@ -228,7 +227,7 @@ class Import_Export extends \Podlove\Modules\Base
 			<input type="file" name="podlove_import_tracking"/>
 			<input type="submit" value="<?php echo __('Import Tracking Data', 'podlove-podcasting-plugin-for-wordpress'); ?>" class="button" />
 			<?php wp_nonce_field('podlove_import_tracking', '_podlove_nonce'); ?>
-		</form>		
+		</form>
 		<?php
     }
 

programming_language: PHP
filename: readme.txt
change_type: ModificationType.MODIFY
diff: @@ -112,6 +112,7 @@ This product includes GeoLite2 data created by MaxMind, available from http://ww
 
 - fix SSRF vulnerability in Slacknotes module
 - add missing capability check and nonce validation to importer functions
+- add missing capability check and nonce validation to exporter functions
 
 = 4.0.11 =
 

programming_language: Markdown