How to exclude or filter password protected posts when using next_post_link() previous_post_link

The function next_post_link() allow excludes, with the parameter excluded_terms. Add a list of the IDs of the password protected posts to this param.

You get a list of all password protected posts with the follow example via DB select.

$password_pages = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_status="publish" AND post_type="post" AND post_password !=''");

Alternative can you use a hook to filter the password protected post from the loop. Also a example below, that works on the single and page view of the front end.

// Filter to hide protected posts
function exclude_protected($where) {
    global $wpdb;
    return $where .= " AND {$wpdb->posts}.post_password = '' ";
}

// Decide where to display them
function exclude_protected_action($query) {
    if( !is_single() && !is_page() && !is_admin() ) {
        add_filter( 'posts_where', 'exclude_protected' );
    }
}

// Action to queue the filter at the right time
add_action('pre_get_posts', 'exclude_protected_action');