Sensitive Data Exposure
Introduction
This article covers cases of possible sensitive data exposure on WordPress. This is a subset of Broken Access Control that impacts confidentiality instead of integrity. This vulnerability occurs due to the lack of a proper confidentiality check on the requested resource.
Actions
Sensitive data can be leaked through hooks or actions when used without consideration for the userβs permissions. Below is an example of vulnerable code:
add_action("wp_ajax_nopriv_view_course", "view_course");
function view_course(){ $course_id = urldecode( $_POST['course_id'] ?? '' );
if ( empty( $course_id ) ) { wp_send_json_error( [ 'message' => 'Invalid Course ID' ] ); }
$course = get_post( $course_id );
wp_send_json_success( [ 'id' => $course->ID, 'title' => $course->post_title, 'content' => $course->post_content, 'excerpt' => $course->post_excerpt, 'url' => get_permalink( $course->ID ), ] );};
To exploit this, any unauthenticated user needs to perform a POST request to the /wp-admin/admin-ajax.php
endpoint specifying the post ID, which is not in the published state, to view any post information. This can lead to an attacker viewing draft, password-protected, and pending posts.
curl <WORDPRESS_BASE_URL>/wp-admin/admin-ajax.php?action=view_course&course_id=1337
Logs
If the logs are stored by the plugin without any .htaccess or randomization of the log filename, it might cause a sensitive data leak.
Below is an example of vulnerable code:
function write_sensitive_log($message) { $log_file = WP_CONTENT_DIR . '/debug.log'; // Predictable and publicly accessible file_put_contents($log_file, $message . "\n", FILE_APPEND);}
add_action('init', function() { if (is_user_logged_in()) { $current_user = wp_get_current_user(); $email = $current_user->user_email; write_sensitive_log('User email: ' . $email); }});
To exploit this, any unauthenticated user can request the URL:
http://<WORDPRESS_BASE_URL>/wp-content/plugins/plugin-name/debug.log
Contributors
