View Issue Details

IDProjectCategoryView StatusLast Update
0021802mantisbtsqlpublic2016-11-07 17:26
Reporterdana Assigned Tocproensa  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.3.2 
Target Version1.3.3Fixed in Version1.3.3 
Summary0021802: Attempting to auto-link very long numbers can cause database errors
Description

Per 0011763:0054235 i'm creating a separate ticket for this.

Mantis uses the following pattern to auto-link bug IDs:

'/(^|[^\w&])' . preg_quote( $t_tag, '/' ) . '(\d+)\b/'

A similar pattern is used to auto-link bug-note IDs.

When it encounters this pattern, it tries to look up the number in the database to see if it exists. (If it doesn't, no auto-linking is performed.)

Since there is no constraint on the number of digits in the pattern, this means Mantis may try looking up very large numbers. In my case, i encountered this because someone had sarcastically written the phrase 'attempt #938402394820928309482034' (no back-slash) in a ticket.

It seems like some databases will simply return no results for the query, but others (like PostgreSQL) will return an error if the number is large enough to exceed the bounds of the bug ID column type.

Steps To Reproduce

These are the steps i took to replicate this with a new Mantis installation:

  1. Download Mantis 1.3.2 and install to appropriate location

  2. Configure Web server

  3. Create new Postgres database and/or credentials for Mantis to use

  4. Configure Mantis to use said credentials

  5. Complete install process

  6. Perform first set-up tasks (change admin password, create project, &c.)

  7. Click Report Issue

  8. Fill in mandatory fields

  9. In the Description field, write the following phrase without the back-slash: attempt #938402394820928309482034

  10. Click Submit

The ticket will submit successfully, but trying to view it will yield the following error:

Database query failed. Error received from database was #-1: ERROR: value "9223372036854775807" is out of range for type integer for the query: SELECT * FROM mantis_bug_table WHERE id=$1.

I didn't notice it on my own installation because i have a bunch of customisations that mitigate it, but on a fresh Mantis installation with the default settings, this error actually seems to prevent access to the ticket entirely.

Additional Information

I've attached patches with two possible mitigations, if you like:

autolink_fix.diff changes the auto-link pattern to ignore numbers with more than 9 digits excluding leading zeroes (999999999).

exists_fix.diff adds a check to bug_exists() and bugnote_exists() to return if the integer-cast number exceeds 2^31 - 1 (2147483647).

The latter is more accurate and addresses the direct cause of the error, but the former probably has fewer implications for the rest of the code base since it only affects auto-linking.

TagsNo tags attached.
Attached Files
autolink_fix.diff (676 bytes)   
--- a/core/string_api.php	2016-10-15 18:57:27.991336119 -0500
+++ b/core/string_api.php	2016-10-15 18:58:38.839177693 -0500
@@ -375,7 +375,7 @@
 	}
 
 	$p_string = preg_replace_callback(
-		'/(^|[^\w&])' . preg_quote( $t_tag, '/' ) . '(\d+)\b/',
+		'/(^|[^\w&])' . preg_quote( $t_tag, '/' ) . '0*(\d{1,9})\b/',
 		$s_bug_link_callback[$p_include_anchor][$p_detail_info][$p_fqdn],
 		$p_string
 	);
@@ -456,7 +456,7 @@
 		}
 	}
 	$p_string = preg_replace_callback(
-		'/(^|[^\w])' . preg_quote( $t_tag, '/' ) . '(\d+)\b/',
+		'/(^|[^\w])' . preg_quote( $t_tag, '/' ) . '0*(\d{1,9})\b/',
 		$s_bugnote_link_callback[$p_include_anchor][$p_detail_info][$p_fqdn],
 		$p_string
 	);
autolink_fix.diff (676 bytes)   
exists_fix.diff (1,139 bytes)   
--- a/core/bug_api.php	2016-10-15 19:24:54.339654674 -0500
+++ b/core/bug_api.php	2016-10-15 19:25:37.379558438 -0500
@@ -830,6 +830,16 @@
 
 	$c_bug_id = (int)$p_bug_id;
 
+	// Prevent very large bug IDs from causing database errors
+	if( $c_bug_id > (2**31) - 1 ) {
+		if( $p_trigger_errors ) {
+			error_parameters( $p_bug_id );
+			trigger_error( ERROR_BUG_NOT_FOUND, ERROR );
+		} else {
+			return false;
+		}
+	}
+
 	db_param_push();
 	$t_query = 'SELECT * FROM {bug} WHERE id=' . db_param();
 	$t_result = db_query( $t_query, array( $c_bug_id ) );
@@ -2176,4 +2186,4 @@
 		}
 	}
 	return $p_new_status;
-}
\ No newline at end of file
+}
--- a/core/bugnote_api.php	2016-10-15 19:25:00.727640390 -0500
+++ b/core/bugnote_api.php	2016-10-15 19:25:48.575533396 -0500
@@ -128,6 +128,11 @@
  * @access public
  */
 function bugnote_exists( $p_bugnote_id ) {
+	// Prevent very large bugnote IDs from causing database errors
+	if( (int)$p_bugnote_id > (2**31) - 1 ) {
+		return false;
+	}
+
 	db_param_push();
 	$t_query = 'SELECT COUNT(*) FROM {bugnote} WHERE id=' . db_param();
 	$t_result = db_query( $t_query, array( $p_bugnote_id ) );
exists_fix.diff (1,139 bytes)   

Relationships

related to 0012880 closeddregad #<long number> in summary/description cause crash 
related to 0014014 closeddregad Search with number > 2147483647 fails on 64-bit systems with PostgreSQL 

Activities

cproensa

cproensa

2016-10-16 06:46

developer   ~0054238

This is reproducible with PostgreSQL

cproensa

cproensa

2016-10-16 08:41

developer   ~0054241

This also affects to the "Issue #, jump" tool

cproensa

cproensa

2016-10-16 10:05

developer   ~0054242

PR:
https://github.com/mantisbt/mantisbt/pull/918/files

I added the check in the xxx_exists functions, as there is where the input validation should be done.

Related Changesets

MantisBT: master-1.3.x 6c95495c

2016-10-16 05:47

cproensa

Committer: vboctor


Details Diff
Prevent db errors for invalid bug/bugnote ids

Some db engines may throw an error if provided with an integer out of
the supported range for field type. As an example: pgsql.
This can happen when the user provides a number high enough as input in
several places. For example:
- Bug and bugnote linking, in texts that are processed by core formatting
plugin
- Bug jump quick access
- Bug id provided for a relation

The core formatting case is especially bad, because the bug page cannot
be rendered, always ending in a db error.

The fix is applied in bug_exists(), and bugnote_exists() functions,
which should fix most of said situations all through the applcation.

Fixes: 0021802
Affected Issues
0021802
mod - core/bug_api.php Diff File
mod - core/bugnote_api.php Diff File
mod - core/constant_inc.php Diff File
mod - core/string_api.php Diff File