VYPR
High severity7.2GHSA Advisory· Published May 11, 2026· Updated May 11, 2026

MantisBT has a Private Bugnote Attachment Content Leak via REST API

CVE-2026-42071

Description

A missing authorization check in MantisBT's file visibility function allows any authenticated user (REPORTER+) to download attachments on private bugnotes they should not be able to access, via the REST API endpoint GET /api/rest/issues/{id}/files and SOAP API mc_issue_attachment_get endpoint.

### Impact - REPORTER (access level 25) can view file attachments that were uploaded to private bugnotes by DEVELOPER/MANAGER/ADMIN users - Private bugnotes are intended for internal developer discussion; their attachments (logs, screenshots, patches) should be equally protected - The web UI is NOT affected — it filters through bugnote_get_all_visible_bugnotes() first

### Patches - 029d9d203d9e4ae96b3e59d552fa7395cc1e5071

Workarounds

None

Credits

Thanks to the following security researchers for independently discovering and responsibly reporting the issue. - Vishal Shukla - Tristan Madani (@TristanInSec) from Talence Security - Tang Cheuk Hei (@siunam321)

This advisory's contents was largely copied from Tristan's well-written report.

Affected products

1

Patches

1
029d9d203d9e

Merge branch 'sec-36985-private-attachment-leak' into release/2.28.2

https://github.com/mantisbt/mantisbtDamien RegadMay 6, 2026via ghsa
3 files changed · +15 21
  • api/soap/mc_file_api.php+5 17 modified
    @@ -23,22 +23,6 @@
      * @link http://www.mantisbt.org
      */
     
    -/**
    - * Check if the current user can download attachments for the specified bug.
    - * @param integer $p_bug_id  A bug identifier.
    - * @param integer $p_user_id A user identifier.
    - * @return boolean
    - */
    -function mci_file_can_download_bug_attachments( $p_bug_id, $p_user_id ) {
    -	$t_can_download = access_has_bug_level( config_get( 'download_attachments_threshold' ), $p_bug_id );
    -	if( $t_can_download ) {
    -		return true;
    -	}
    -
    -	$t_reported_by_me = bug_is_user_reporter( $p_bug_id, $p_user_id );
    -	return( $t_reported_by_me && config_get( 'allow_download_own_attachments' ) );
    -}
    -
     /**
      * Read a local file and return its content.
      * @param string $p_diskfile Name of file on disk.
    @@ -222,6 +206,8 @@ function mci_file_get( $p_file_id, $p_type, $p_user_id ) {
     		$t_project_id = $t_row['project_id'];
     	} else if( $p_type == 'bug' ) {
     		$t_bug_id = $t_row['bug_id'];
    +		$t_bugnote_id = $t_row['bugnote_id'];
    +		$t_owner_id = $t_row['user_id'];
     		$t_project_id = bug_get_field( $t_bug_id, 'project_id' );
     	}
     
    @@ -231,7 +217,9 @@ function mci_file_get( $p_file_id, $p_type, $p_user_id ) {
     	# Check access rights
     	switch( $p_type ) {
     		case 'bug':
    -			if( !mci_file_can_download_bug_attachments( $t_bug_id, $p_user_id ) ) {
    +			if( !file_can_download_bug_attachments( $t_bug_id, $t_owner_id )
    +				|| !file_can_download_bugnote_attachments( $t_bugnote_id, $t_owner_id, $t_bug_id )
    +			) {
     				return mci_fault_access_denied( $p_user_id );
     			}
     			break;
    
  • core/file_api.php+9 3 modified
    @@ -309,7 +309,7 @@ function file_can_view_bugnote_attachments( $p_bugnote_id, $p_uploader_user_id =
     		$t_bug_id = (int)$p_bug_id;
     	}
     
    -	return file_can_view_or_download( 'view', $t_bug_id, $p_uploader_user_id );
    +	return file_can_view_or_download( 'view', $t_bug_id, $p_uploader_user_id, $p_bugnote_id );
     }
     
     /**
    @@ -330,15 +330,21 @@ function file_can_download_bug_attachments( $p_bug_id, $p_uploader_user_id = nul
      *
      * @param int $p_bugnote_id       A bugnote identifier.
      * @param int $p_uploader_user_id The user who uploaded the attachment.
    + * @param int $p_bug_id           The bug id; if null (default), will be retrieved
    + *                                from bugnote record.
      *
      * @return bool
      * @throws ClientException
      */
    -function file_can_download_bugnote_attachments( $p_bugnote_id, $p_uploader_user_id = null ) {
    +function file_can_download_bugnote_attachments( $p_bugnote_id, $p_uploader_user_id = null, $p_bug_id = null ) {
     	if( $p_bugnote_id == 0 ) {
     		return true;
     	}
    -	$t_bug_id = bugnote_get_field( $p_bugnote_id, 'bug_id' );
    +	if( $p_bug_id === null ) {
    +		$t_bug_id = bugnote_get_field( $p_bugnote_id, 'bug_id' );
    +	} else {
    +		$t_bug_id = (int)$p_bug_id;
    +	}
     	return file_can_view_or_download( 'download', $t_bug_id, $p_uploader_user_id, $p_bugnote_id );
     }
     
    
  • file_download.php+1 1 modified
    @@ -123,7 +123,7 @@
     switch( $f_type ) {
     	case 'bug':
     		if( !file_can_download_bug_attachments( $v_bug_id, $v_user_id )
    -		|| !file_can_download_bugnote_attachments( $v_bugnote_id, $v_user_id )
    +		|| !file_can_download_bugnote_attachments( $v_bugnote_id, $v_user_id, $v_bug_id )
     		) {
     			access_denied();
     		}
    

Vulnerability mechanics

AI mechanics synthesis has not run for this CVE yet.

References

7

News mentions

0

No linked articles in our index yet.