jenkins-bot has submitted this change and it was merged.
Change subject: Add a way to redact certain function parameters from exception
stack traces
......................................................................
Add a way to redact certain function parameters from exception stack traces
Bug: 30714
Change-Id: I0a9e92448f8d9009dd594cb4d7f5dc6fdd4bcc86
---
M RELEASE-NOTES-1.22
M includes/DefaultSettings.php
M includes/Exception.php
3 files changed, 88 insertions(+), 7 deletions(-)
Approvals:
Reedy: Looks good to me, approved
jenkins-bot: Verified
diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22
index 94a9dfd..3ba86f5 100644
--- a/RELEASE-NOTES-1.22
+++ b/RELEASE-NOTES-1.22
@@ -216,6 +216,8 @@
* Add deferrable update support for callback/closure
* Add TitleMove hook before page renames
* Revision deletion backend code is moved out of SpecialRevisiondelete
+* Add a variable (wgRedactedFunctionArguments) to redact the values sent as
certain function
+ parameters from exception stack traces.
=== Bug fixes in 1.22 ===
* Disable Special:PasswordReset when $wgEnableEmail is false. Previously one
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 22b7f1e..51c6c3d 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -4881,6 +4881,37 @@
$wgShowExceptionDetails = false;
/**
+ * Array of functions which need parameters redacted from stack traces shown to
+ * clients and logged. Keys are in the format '[class::]function', and the
+ * values should be either an integer or an array of integers. These are the
+ * indexes of the parameters which need to be kept secret.
+ * @since 1.22
+ */
+$wgRedactedFunctionArguments = array(
+ 'AuthPlugin::setPassword' => 1,
+ 'AuthPlugin::authenticate' => 1,
+ 'AuthPlugin::addUser' => 1,
+
+ 'DatabaseBase::__construct' => 2,
+ 'DatabaseBase::open' => 2,
+
+ 'SpecialChangeEmail::attemptChange' => 1,
+ 'SpecialChangePassword::attemptReset' => 0,
+
+ 'User::setPassword' => 0,
+ 'User::setInternalPassword' => 0,
+ 'User::checkPassword' => 0,
+ 'User::setNewpassword' => 0,
+ 'User::comparePasswords' => array( 0, 1 ),
+ 'User::checkTemporaryPassword' => 0,
+ 'User::setToken' => 0,
+ 'User::crypt' => 0,
+ 'User::oldCrypt' => 0,
+ 'User::getPasswordValidity' => 0,
+ 'User::isValidPassword' => 0,
+);
+
+/**
* If true, show a backtrace for database errors
*/
$wgShowDBErrorBacktrace = false;
diff --git a/includes/Exception.php b/includes/Exception.php
index e1bfb2d..39fe6f4 100644
--- a/includes/Exception.php
+++ b/includes/Exception.php
@@ -127,7 +127,7 @@
if ( $wgShowExceptionDetails ) {
return '<p>' . nl2br( htmlspecialchars(
$this->getMessage() ) ) .
- '</p><p>Backtrace:</p><p>' . nl2br(
htmlspecialchars( $this->getTraceAsString() ) ) .
+ '</p><p>Backtrace:</p><p>' . nl2br(
htmlspecialchars( MWExceptionHandler::formatRedactedTrace( $this ) ) ) .
"</p>\n";
} else {
return "<div class=\"errorbox\">" .
@@ -152,7 +152,7 @@
if ( $wgShowExceptionDetails ) {
return $this->getMessage() .
- "\nBacktrace:\n" . $this->getTraceAsString() .
"\n";
+ "\nBacktrace:\n" .
MWExceptionHandler::formatRedactedTrace( $this ) . "\n";
} else {
return "Set \$wgShowExceptionDetails = true; " .
"in LocalSettings.php to show detailed
debugging information.\n";
@@ -275,7 +275,7 @@
$log = $this->getLogMessage();
if ( $log ) {
if ( $wgLogExceptionBacktrace ) {
- wfDebugLog( 'exception', $log . "\n" .
$this->getTraceAsString() . "\n" );
+ wfDebugLog( 'exception', $log . "\n" .
MWExceptionHandler::formatRedactedTrace( $this ) . "\n" );
} else {
wfDebugLog( 'exception', $log );
}
@@ -633,7 +633,7 @@
$message = "MediaWiki internal error.\n\n";
if ( $wgShowExceptionDetails ) {
- $message .= 'Original exception: ' .
$e->__toString() . "\n\n" .
+ $message .= 'Original exception: ' .
self::formatRedactedTrace( $e ) . "\n\n" .
'Exception caught inside
exception handler: ' . $e2->__toString();
} else {
$message .= "Exception caught inside
exception handler.\n\n" .
@@ -650,11 +650,10 @@
}
}
} else {
- $message = "Unexpected non-MediaWiki exception
encountered, of type \"" . get_class( $e ) . "\"\n" .
- $e->__toString() . "\n";
+ $message = "Unexpected non-MediaWiki exception
encountered, of type \"" . get_class( $e ) . "\"";
if ( $wgShowExceptionDetails ) {
- $message .= "\n" . $e->getTraceAsString() .
"\n";
+ $message .= "\nexception '" . get_class( $e ) .
"' in " . $e->getFile() . ":" . $e->getLine() . "\nStack trace:\n" .
self::formatRedactedTrace( $e ) . "\n";
}
if ( $cmdLine ) {
@@ -709,4 +708,53 @@
// Exit value should be nonzero for the benefit of shell jobs
exit( 1 );
}
+
+ /**
+ * Get the stack trace from the exception as a string, redacting
certain function arguments in the process
+ * @param Exception $e The exception
+ * @return string The stack trace as a string
+ */
+ public static function formatRedactedTrace( Exception $e ) {
+ global $wgRedactedFunctionArguments;
+ $finalExceptionText = '';
+
+ foreach ( $e->getTrace() as $i => $call ) {
+ $checkFor = array();
+ if ( isset( $call['class'] ) ) {
+ $checkFor[] = $call['class'] . '::' .
$call['function'];
+ foreach ( class_parents( $call['class'] ) as
$parent ) {
+ $checkFor[] = $parent . '::' .
$call['function'];
+ }
+ } else {
+ $checkFor[] = $call['function'];
+ }
+
+ foreach ( $checkFor as $check ) {
+ if ( isset(
$wgRedactedFunctionArguments[$check] ) ) {
+ foreach (
(array)$wgRedactedFunctionArguments[$check] as $argNo ) {
+ $call['args'][$argNo] =
'REDACTED';
+ }
+ }
+ }
+
+ $finalExceptionText .= "#{$i}
{$call['file']}({$call['line']}): ";
+ if ( isset( $call['class'] ) ) {
+ $finalExceptionText .= $call['class'] .
$call['type'] . $call['function'];
+ } else {
+ $finalExceptionText .= $call['function'];
+ }
+ $args = array();
+ foreach ( $call['args'] as $arg ) {
+ if ( is_object( $arg ) ) {
+ $args[] = 'Object(' . get_class( $arg )
. ')';
+ } elseif( is_array( $arg ) ) {
+ $args[] = 'Array';
+ } else {
+ $args[] = var_export( $arg, true );
+ }
+ }
+ $finalExceptionText .= '(' . implode( ', ', $args ) .
")\n";
+ }
+ return $finalExceptionText . '#' . ( $i + 1 ) . ' {main}';
+ }
}
--
To view, visit https://gerrit.wikimedia.org/r/64450
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I0a9e92448f8d9009dd594cb4d7f5dc6fdd4bcc86
Gerrit-PatchSet: 11
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Alex Monk <[email protected]>
Gerrit-Reviewer: Alex Monk <[email protected]>
Gerrit-Reviewer: CSteipp <[email protected]>
Gerrit-Reviewer: Chad <[email protected]>
Gerrit-Reviewer: Parent5446 <[email protected]>
Gerrit-Reviewer: Reedy <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits