View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0036902 | mantisbt | security | public | 2026-03-01 12:03 | 2026-03-23 13:22 |
| Reporter | joward | Assigned To | dregad | ||
| Priority | immediate | Severity | major | Reproducibility | have not tried |
| Status | closed | Resolution | fixed | ||
| Product Version | 2.3.0 | ||||
| Target Version | 2.28.1 | Fixed in Version | 2.28.1 | ||
| Summary | 0036902: CVE-2026-30849: Authentication bypass vulnerability in the SOAP API | ||||
| Description | Mantis Bug Tracker The majority of SOAP operations are authenticated, and in some form call to mci_check_login in api/soap/mc_api.php to perform the authentication. This function contains a conditional statement that reaches auth_user_id_from_cookie at line 480, which serves as a wrapper for user_get_id_by_cookie. If auth_user_id_from_cookie returns a valid row, it will call to auth_attempt_script_login with the provided username and no password, as the application assumes that a valid row means that the provided cookies was valid. Once it reaches this function, it will successfully log the user in with the provided username. user_get_id_by_cookie expects the p_cookie_string parameter to be a string. However, if a user is able to pass in an integer that is not converted to a string, the SQL SELECT statement will attempt to query the database using an integer for its check, i.e. SELECT * FROM mantis_user_table WHERE cookie_string=0. MySQL will attempt to CAST the cookie_string to an integer to perform the check without throwing an error. One of two things will happen:
As such, so long as there is a cookie_string that does not have a leading integer, which is highly likely, passing in 0 as the p_cookie_string parameter will successfully return several rows and pass this check. If there is no cookie_string that does not start with a leading integer, it would be possible to iterate from 1-9 to eventually retrieve a row and pass this check. SOAP envelopes can have defined namespaces that preserve the type the user defines on the parameter, i.e. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema". As a result, an attacker can explicitly type the password as an integer, pass in 0 (or iterate through other integers if necessary), define the username as administrator, pass the check in user_get_id_by_cookie, and successfully log in as the administrator. The impact for this is quite high. The SOAP API does not perform any user operations, nor have I identified any additional vulnerabilities that may allow for a server side compromise. However, as the default username is administrator, it's possible for an unauthenticated user to act as an administrator on all tickets and projects, including private tickets. | ||||
| Steps To Reproduce | Reproduction requires a properly formatted SOAP envelope with the xmlns:xsi and xmlns:xsd namespaces defined in order to preserve the integer type on the password. A properly formatted POST request to /api/soap/mantisconnect.php to authenticate as the administrator is shown below: POST /api/soap/mantisconnect.php HTTP/1.1 <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_login><username>administrator</username><password xsi:type="xsd:integer">0</password></mc:mc_login></soapenv:Body></soapenv:Envelope> | ||||
| Additional Information | I'm not certain which minor version first introduced this issue. Checking through your Git commit history, it looks like it the user_get_id_by_cookie function was first introduced in version 2.25.0 in commit 65ebd29 on March 5th, 2021. Additionally, I would appreciate being credited in the CVE for this as Alexander Philiotis of SynerComm. Please let me know if there's any additional explanation or context I can provide. Thank you! | ||||
| Tags | No tags attached. | ||||
|
Hello, and many thanks for the detailed report. I will investigate and get back to you as soon as possible. I will open a security advisory on GitHub, and request a CVE ID unless you have already obtained one (if so, let me know the number). Also, could you please tell me your GitHub username so I can add you to the advisory. |
|
|
Sounds good. I have not yet requested a CVE. My GitHub is https://github.com/JBince Thanks! |
|
|
Thanks for your patience @joward, I've had a busy week and did not find time to look into this until now. I can confirm the reported behavior, i.e. knowing a username, it is possible to login via SOAP without knowing the account's password.
I tested with 2.24.x (before the user_get_id_by_cookie() function was introduced), and the vulnerability is also present there, because the older auth_user_id_from_cookie() function executes the exact same database query. That code was introduced in 2017 commit MantisBT master b7c14c79 (MantisBT 2.3.0). The bug was probably not present < 2.3.0, but I can't confirm that 100% due to PHP obsolescence, as I do not have a working environment where I could actually test this right now. I think it's not worth the effort to set that up, so I'll simply publish the advisory stating that all versions <= 2.28.0 are affected. I believe the fix should be pretty straightforward - casting $p_password to string will probably do the trick. |
|
|
Draft Advisory created https://github.com/mantisbt/mantisbt/security/advisories/GHSA-phrq-pc6r-f6gh and CVE ID requested. Please review and let me know if anything should be changed. I'll post the patch tomorrow. |
|
|
@joward Thanks in advance |
|
|
CVE-2026-30849 assigned. |
|
|
@joward any feedback on the proposed patch ? Without news from you by Friday I'll publish the advisory, merge the change and release 2.28.1 with the fix. |
|
|
Going public. |
|
|
MantisBT: master-2.28 b349e5c8 2026-03-06 11:17 Details Diff |
Add type definition to mci_check_login()'s params Enforcing string type for $p_password prevents authentication bypass on MySQL (CVE-2026-30849). Note that null must be accepted as well, because SOAP API consumers are allowed to send an XML payload without a password (e.g. for anonymous login). For consistency, the type definition is also applied to $p_username. Fixes 0036902, GHSA-fh48-f69w-7vmp |
Affected Issues 0036902 |
|
| mod - api/soap/mc_api.php | Diff File | ||