From 4b436c4c91054f02681f05651e1e6e4a1eb56751 Mon Sep 17 00:00:00 2001 From: Victor Boctor Date: Sun, 19 Apr 2020 14:36:47 -0700 Subject: [PATCH] Fix attachments API access checks - Fix attachment access checks for private attachments. (REST and SOAP) - Include note attachments within notes (REST) Fixes #26893 --- api/soap/mc_issue_api.php | 12 ++++++++++-- core/file_api.php | 12 ++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/api/soap/mc_issue_api.php b/api/soap/mc_issue_api.php index 7600f583bd..b300ea08a6 100644 --- a/api/soap/mc_issue_api.php +++ b/api/soap/mc_issue_api.php @@ -501,9 +501,10 @@ function mci_issue_get_custom_fields( $p_issue_id ) { * Get the attachments of an issue. * * @param integer $p_issue_id The id of the issue to retrieve the attachments for. + * @param integer $p_note_id 0 for issue attachments, an id for note attachments, null for all * @return array that represents an AttachmentData structure */ -function mci_issue_get_attachments( $p_issue_id ) { +function mci_issue_get_attachments( $p_issue_id, $p_note_id = null ) { $t_attachment_rows = file_get_visible_attachments( $p_issue_id ); if( $t_attachment_rows == null ) { return array(); @@ -511,6 +512,11 @@ function mci_issue_get_attachments( $p_issue_id ) { $t_result = array(); foreach( $t_attachment_rows as $t_attachment_row ) { + # Filter out attachments that are not requested by caller + if( !is_null( $p_note_id ) && (int)$t_attachment_row['bugnote_id'] != (int)$p_note_id ) { + continue; + } + $t_attachment = array(); $t_attachment['id'] = (int)$t_attachment_row['id']; @@ -636,6 +642,8 @@ function mci_issue_note_data_as_array( $p_bugnote_row ) { $t_bugnote['date_submitted'] = $t_created_at; $t_bugnote['last_modified'] = $t_modified_at; } else { + $t_bugnote['attachments'] = mci_issue_get_attachments( $p_bugnote_row->bug_id, $p_bugnote_row->id ); + switch( $p_bugnote_row->note_type ) { case REMINDER: $t_type = 'reminder'; @@ -1685,7 +1693,7 @@ function mci_issue_data_as_array( BugData $p_issue_data, $p_user_id, $p_lang ) { } # Get attachments - access checked as part of returning attachments - $t_issue['attachments'] = mci_issue_get_attachments( $p_issue_data->id ); + $t_issue['attachments'] = mci_issue_get_attachments( $p_issue_data->id, /* note_id */ 0 ); # Get notes - access checked as part of returning notes. $t_issue['notes'] = mci_issue_get_notes( $p_issue_data->id ); diff --git a/core/file_api.php b/core/file_api.php index 9756001deb..a4bee89898 100644 --- a/core/file_api.php +++ b/core/file_api.php @@ -372,16 +372,28 @@ function file_get_visible_attachments( $p_bug_id ) { $t_preview_text_ext = config_get( 'preview_text_extensions' ); $t_preview_image_ext = config_get( 'preview_image_extensions' ); + $t_attachments_view_threshold = config_get( 'view_attachments_threshold' ); $t_image_previewed = false; for( $i = 0;$i < $t_attachments_count;$i++ ) { $t_row = $t_attachment_rows[$i]; $t_user_id = (int)$t_row['user_id']; + # This covers access checks for issue attachments if( !file_can_view_bug_attachments( $p_bug_id, $t_user_id ) ) { continue; } + # This covers access checks for issue note attachments + $t_attachment_note_id = (int)$t_row['bugnote_id']; + if( $t_attachment_note_id !== 0 ) { + if( bugnote_get_field( $t_attachment_note_id, 'view_state' ) != VS_PUBLIC ) { + if( !access_has_bugnote_level( $t_attachments_view_threshold, $t_attachment_note_id ) ) { + continue; + } + } + } + $t_id = (int)$t_row['id']; $t_filename = $t_row['filename']; $t_filesize = $t_row['filesize'];