protect_database_details.diff (21,749 bytes)
diff --git a/config_editor.php b/config_editor.php
index 863f342a8f1ad5e3b95b8e9798b05606d194683b..4074d7e43e0e018c9a5d941ab90aae89a9739403 100644
--- a/config_editor.php
+++ b/config_editor.php
@@ -219,6 +219,7 @@ function do_access($given_password)
'prefer_direct_code_call' => '<em>Tuning:</em> Whether to assume a good opcode cache is present, so load up full code files via this rather than trying to save RAM by loading up small parts of files on occasion.',
+ 'protect_database_details' => '<em>Security:</em> Limit what information is disclosed when showing an error message relating to the database.',
'backdoor_ip' => '<em>Security:</em> Always allow users accessing from this IP address in, automatically logged in as the oldest admin of the site.',
'full_ips' => '<em>Security:</em> Whether to match sessions to the full IP addresses. Set this to 1 if you are sure users don\'t jump around IP addresses on the same 255.255.255.0 subnet (e.g. due to proxy server randomisation).',
/* Don't want this in here, we want it autodetected unless explicitly overridden
diff --git a/lang/EN/critical_error.ini b/lang/EN/critical_error.ini
index a963da830e9e8387445c68bf743df81b76ce7dbc..9546a88d1132d25e6714435aa74802b30e413648 100644
--- a/lang/EN/critical_error.ini
+++ b/lang/EN/critical_error.ini
@@ -166,13 +166,14 @@ ONLY_LOCAL_HOST_FOR_TYPE=This database driver only works over 'localhost'
QUERY_FAILED=Unfortunately a query has failed [{1}] [<strong>{2}</strong>]
QUERY_FAILED_TOO_BIG=Unfortunately a query of {2} bytes is too big for the current MySQL <kbd>max_allowed_packet</kbd> setting of {3} bytes [{1}]
QUERY_NULL=A query that had to return something returned nothing: {1}
+QUERY_FAILED_GENERIC=A database operation has failed.
MUST_DELETE_INSTALLER=You must delete the <kbd>install.php</kbd> file immediately, or your installation is open to erasure by anyone; if you installed via the official copy-to-hosting feature then you will be able to see and delete this file if you open up FTP manually
ERROR_OCCURRED=An error has occurred
ERROR_OCCURRED_SUBJECT=An error occurred on the '{1}' page
SOME_ERRORS_OCCURRED=Some errors occurred during the action
CORRUPT_FILE=A file, {1} is either corrupt or a filetype not recognised by this part of the website software
STACK_TRACE=Here is the stack trace:
-STACK_TRACE_DENIED_ERROR_NOTIFICATION=The staff have been provided a ‘stack trace’ which may help them diagnose the problem.
+STACK_TRACE_DENIED_ERROR_NOTIFICATION=The staff have been provided further information which may help them diagnose the problem.
CONNECT_ERROR=Could not connect to the database with the database username you specified
CONNECT_DB_ERROR=Could not connect to the database
NO_PARAMETER_SENT=A critical parameter, <kbd>{1}</kbd>, was missing.
diff --git a/sources/database.php b/sources/database.php
index ddf97706b485ced6f7597660c7df9e3b7914e78b..a087a060915588706c891ca68cc39fd717c09e01 100644
--- a/sources/database.php
+++ b/sources/database.php
@@ -1147,7 +1147,7 @@ class DatabaseConnector
return null; // error
}
if (!array_key_exists(0, $values)) {
- fatal_exit(do_lang_tempcode('QUERY_NULL', escape_html($this->_get_where_expand($this->table_prefix . $table, array($selected_value), $where_map, $end)))); // No result found
+ fatal_exit_query(do_lang_tempcode('QUERY_NULL', escape_html($this->_get_where_expand($this->table_prefix . $table, array($selected_value), $where_map, $end)))); // No result found
}
return $this->_query_select_value($values);
}
@@ -2000,3 +2000,64 @@ class DatabaseConnector
return $locked;
}
}
+
+/**
+ * Equivalent to fatal_exit, but will substitute a vague error message based on configuration to avoid information disclosure.
+ * Real error message would be preserved in a stack trace.
+ *
+ * @param mixed $text The error message (string or Tempcode)
+ */
+function fatal_exit_query($text)
+{
+ global $SITE_INFO;
+ if ((isset($SITE_INFO['protect_database_details'])) && ($SITE_INFO['protect_database_details'] == '1') && (!running_script('upgrader')) && (!running_script('execute_temp'))) {
+ if (!function_exists('do_lang') || (do_lang('QUERY_FAILED_GENERIC', null, null, null, null, false) === null)) {
+ $new_text = 'A database operation has failed.';
+ } else {
+ $new_text = do_lang('QUERY_FAILED_GENERIC');
+ }
+ } else {
+ $new_text = $text;
+ }
+ fatal_exit($new_text);
+}
+
+/**
+ * Equivalent to attach_message, but will substitute a vague error message based on configuration to avoid information disclosure.
+ * Real error message would be preserved in a stack trace if triggered.
+ *
+ * @sets_output_state
+ *
+ * @param mixed $message The message
+ */
+function attach_message_query($message)
+{
+ global $SITE_INFO;
+ if ((isset($SITE_INFO['protect_database_details'])) && ($SITE_INFO['protect_database_details'] == '1') && (!running_script('upgrader')) && (!running_script('execute_temp'))) {
+ if (!function_exists('do_lang') || (do_lang('QUERY_FAILED_GENERIC', null, null, null, null, false) === null)) {
+ $message = 'A database operation has failed.';
+ } else {
+ $message = do_lang('QUERY_FAILED_GENERIC');
+ }
+ }
+ attach_message($message, 'warn');
+}
+
+/**
+ * Outputs a message, but will substitute a vague error message based on configuration to avoid information disclosure.
+ * Real error message would be preserved in a stack trace if triggered.
+ *
+ * @param mixed $message The message
+ */
+function echo_message_query($message)
+{
+ global $SITE_INFO;
+ if ((isset($SITE_INFO['protect_database_details'])) && ($SITE_INFO['protect_database_details'] == '1') && (!running_script('upgrader')) && (!running_script('execute_temp'))) {
+ if (!function_exists('do_lang') || (do_lang('QUERY_FAILED_GENERIC', null, null, null, null, false) === null)) {
+ $message = 'A database operation has failed.';
+ } else {
+ $message = do_lang('QUERY_FAILED_GENERIC');
+ }
+ }
+ echo $message . "<br />\n";
+}
diff --git a/sources/database/access.php b/sources/database/access.php
index 8e47c0a1d1a65daeab304f672691717676501c57..744f1b50bd1232d9e08cad2b69336fdd56f9b40f 100644
--- a/sources/database/access.php
+++ b/sources/database/access.php
@@ -374,12 +374,12 @@ class Database_Static_access
}
if ((!running_script('upgrader')) && ((!get_mass_import_mode()) || (get_param_integer('keep_fatalistic', 0) == 1))) {
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
diff --git a/sources/database/ibm.php b/sources/database/ibm.php
index 4782ff817642aac08309c7096fc815bf6424eda7..a39c378aa82027943121fdba031dc1319c3959f1 100644
--- a/sources/database/ibm.php
+++ b/sources/database/ibm.php
@@ -358,12 +358,12 @@ class Database_Static_ibm
}
if ((!running_script('upgrader')) && ((!get_mass_import_mode()) || (get_param_integer('keep_fatalistic', 0) == 1))) {
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
diff --git a/sources/database/mysql.php b/sources/database/mysql.php
index 1eb490eb4d400cdbe2aabd0ce6fe46fd8e920cba..39d816b000c4010cfef7293c0a79c30fd6de5b38 100644
--- a/sources/database/mysql.php
+++ b/sources/database/mysql.php
@@ -212,9 +212,9 @@ class Database_Static_mysql extends Database_super_mysql
/*@mysql_query('SET max_allowed_packet=' . strval(intval(strlen($query) * 1.3)), $db); Does not work well, as MySQL server has gone away error will likely just happen instead */
if ($get_insert_id) {
- fatal_exit(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html($query), escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html($query), escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
} else {
- attach_message(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html(substr($query, 0, 300)) . '...', escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))), 'warn');
+ attach_message_query(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html(substr($query, 0, 300)) . '...', escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
}
return null;
}
@@ -260,11 +260,11 @@ class Database_Static_mysql extends Database_super_mysql
}
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
diff --git a/sources/database/mysql_dbx.php b/sources/database/mysql_dbx.php
index 1a589d8f59bb7bbb3cfb0ec168b02e2de4a8956b..1a3241fcbec0ba079ef786fdae182f661f520779 100644
--- a/sources/database/mysql_dbx.php
+++ b/sources/database/mysql_dbx.php
@@ -182,9 +182,9 @@ class Database_Static_mysql_dbx extends Database_super_mysql
/*@mysql_query('SET max_allowed_packet=' . strval(intval(strlen($query) * 1.3)), $db); Does not work well, as MySQL server has gone away error will likely just happen instead */
if ($get_insert_id) {
- fatal_exit(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html($query), escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html($query), escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
} else {
- attach_message(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html(substr($query, 0, 300)) . '...', escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))), 'warn');
+ attach_message_query(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html(substr($query, 0, 300)) . '...', escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
}
return null;
}
@@ -211,11 +211,11 @@ class Database_Static_mysql_dbx extends Database_super_mysql
}
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
diff --git a/sources/database/mysqli.php b/sources/database/mysqli.php
index 6243335ac8fc7db728495b673b984af7322582ac..03f9ca11afd020769b8862f0795505db9c733a4d 100644
--- a/sources/database/mysqli.php
+++ b/sources/database/mysqli.php
@@ -213,9 +213,9 @@ class Database_Static_mysqli extends Database_super_mysql
/*@mysql_query('SET max_allowed_packet=' . strval(intval(strlen($query) * 1.3)), $db); Does not work well, as MySQL server has gone away error will likely just happen instead */
if ($get_insert_id) {
- fatal_exit(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html($query), escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html($query), escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
} else {
- attach_message(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html(substr($query, 0, 300)) . '...', escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))), 'warn');
+ attach_message_query(do_lang_tempcode('QUERY_FAILED_TOO_BIG', escape_html(substr($query, 0, 300)) . '...', escape_html(integer_format(strlen($query))), escape_html(integer_format(intval($test_result[0]['Value'])))));
}
return null;
}
@@ -265,11 +265,11 @@ class Database_Static_mysqli extends Database_super_mysql
}
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
diff --git a/sources/database/oracle.php b/sources/database/oracle.php
index 9ec3ceef2fd14b2f83aa7e4701f784d772acf874..e5a9115e8bcbf76778e9875d5fe3996c7aae04d0 100644
--- a/sources/database/oracle.php
+++ b/sources/database/oracle.php
@@ -468,12 +468,12 @@ class Database_Static_oracle
}
if ((!running_script('upgrader')) && ((!get_mass_import_mode()) || (get_param_integer('keep_fatalistic', 0) == 1))) {
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
@@ -529,7 +529,7 @@ class Database_Static_oracle
$v = $v->load(); // For CLOB's
}
if ($v === false) {
- fatal_exit(do_lang_tempcode('QUERY_FAILED', ocierror($stmt)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', ocierror($stmt)));
}
$name = $names[$j];
diff --git a/sources/database/postgresql.php b/sources/database/postgresql.php
index 41d80c1e2e9b46baaf96a5d006cda0fab5a154c7..1a2d9b06d90d9115ed3b411dcd7e603a5e9d515f 100644
--- a/sources/database/postgresql.php
+++ b/sources/database/postgresql.php
@@ -464,12 +464,12 @@ class Database_Static_postgresql
}
if ((!running_script('upgrader')) && ((!get_mass_import_mode()) || (get_param_integer('keep_fatalistic', 0) == 1))) {
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
diff --git a/sources/database/sqlite.php b/sources/database/sqlite.php
index 768703b4f190e24a5c902005db32129e328f9bac..cb8f9dc00c9b63fd3593a13051a16dbc386f1f59 100644
--- a/sources/database/sqlite.php
+++ b/sources/database/sqlite.php
@@ -371,12 +371,12 @@ class Database_Static_sqlite
}
if ((!running_script('upgrader')) && ((!get_mass_import_mode()) || (get_param_integer('keep_fatalistic', 0) == 1))) {
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}
diff --git a/sources/database/sqlserver.php b/sources/database/sqlserver.php
index 5019528e3b16937f9011d23d945693e81d03d71a..a4c660f116583c3770a99f4d88080d692fd11a8e 100644
--- a/sources/database/sqlserver.php
+++ b/sources/database/sqlserver.php
@@ -490,12 +490,12 @@ class Database_Static_sqlserver
}
if ((!running_script('upgrader')) && ((!get_mass_import_mode()) || (get_param_integer('keep_fatalistic', 0) == 1))) {
if (!function_exists('do_lang') || is_null(do_lang('QUERY_FAILED', null, null, null, null, false))) {
- fatal_exit(htmlentities('Query failed: ' . $query . ' : ' . $err));
+ fatal_exit_query(htmlentities('Database query failed: ' . $query . ' : ' . $err));
}
- fatal_exit(do_lang_tempcode('QUERY_FAILED', escape_html($query), ($err)));
+ fatal_exit_query(do_lang_tempcode('QUERY_FAILED', escape_html($query), $err));
} else {
- echo htmlentities('Database query failed: ' . $query . ' [') . ($err) . htmlentities(']') . "<br />\n";
+ echo_message_query(htmlentities('Database query failed: ' . $query . ' [') . $err . htmlentities(']'));
return null;
}
}