diff options
author | Lukas Reschke <lukas@owncloud.com> | 2014-09-11 14:14:02 +0200 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2014-09-17 13:17:52 +0200 |
commit | 6d3757f8648cb94b2ba04c6a5bfbc9dd1493103b (patch) | |
tree | 0cef084c3140b52a4ced70acc6ede3eb52cf33ab | |
parent | 45b17207ccf03703d4d6c3925f5405f52579aee5 (diff) | |
download | nextcloud-server-6d3757f8648cb94b2ba04c6a5bfbc9dd1493103b.tar.gz nextcloud-server-6d3757f8648cb94b2ba04c6a5bfbc9dd1493103b.zip |
Do not show exception to the end-user
Log the error instead of potentially leaking sensitive information
-rw-r--r-- | core/templates/error.php | 4 | ||||
-rw-r--r-- | core/templates/exception.php | 28 | ||||
-rwxr-xr-x | index.php | 3 | ||||
-rw-r--r-- | lib/private/hintexception.php | 2 | ||||
-rw-r--r-- | lib/private/log/owncloud.php | 11 | ||||
-rwxr-xr-x | lib/private/request.php | 14 | ||||
-rw-r--r-- | lib/private/template.php | 37 | ||||
-rw-r--r-- | lib/public/util.php | 38 |
8 files changed, 74 insertions, 63 deletions
diff --git a/core/templates/error.php b/core/templates/error.php index e8b7a49264f..030fbf07fcb 100644 --- a/core/templates/error.php +++ b/core/templates/error.php @@ -2,7 +2,9 @@ <?php foreach($_["errors"] as $error):?> <li class='error'> <?php p($error['error']) ?><br/> - <p class='hint'><?php if(isset($error['hint']))print_unescaped($error['hint']) ?></p> + <?php if(isset($error['hint']) && $error['hint']): ?> + <p class='hint'><?php print_unescaped($error['hint']) ?></p> + <?php endif;?> </li> <?php endforeach ?> </ul> diff --git a/core/templates/exception.php b/core/templates/exception.php new file mode 100644 index 00000000000..a5944e491cc --- /dev/null +++ b/core/templates/exception.php @@ -0,0 +1,28 @@ +<?php + /** @var array $_ */ + /** @var OC_L10N $l */ +?> +<span class="error error-wide"> + <h2><strong><?php p('Internal Server Error') ?></strong></h2><br/> + <p><?php p($l->t('The server encountered an internal error and was unable to complete your request.')) ?></p> + <p><?php p($l->t('Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.')) ?></p> + <p><?php p($l->t('More details can be found in the server log.')) ?></p> + <hr/> + <h2><strong><?php p($l->t('Technical details')) ?></strong></h2> + <ul> + <li><?php p($l->t('Remote Address: %s', $_['remoteAddr'])) ?></li> + <li><?php p($l->t('Request ID: %s', $_['requestID'])) ?></li> + <?php if($_['debugMode']): ?> + <li><?php p($l->t('Code: %s', $_['errorCode'])) ?></li> + <li><?php p($l->t('Message: %s', $_['errorMsg'])) ?></li> + <li><?php p($l->t('File: %s', $_['file'])) ?></li> + <li><?php p($l->t('Line: %s', $_['line'])) ?></li> + <?php endif; ?> + </ul> + + <?php if($_['debugMode']): ?> + <hr/> + <h2><strong><?php p($l->t('Trace')) ?></strong></h2> + <pre><?php p($_['trace']) ?></pre> + <?php endif; ?> +</span> diff --git a/index.php b/index.php index 061391892fe..88d5733cb37 100755 --- a/index.php +++ b/index.php @@ -33,6 +33,9 @@ try { //show the user a detailed error page OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); OC_Template::printExceptionErrorPage($ex); +} catch (\OC\HintException $ex) { + OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); + OC_Template::printErrorPage($ex->getMessage(), $ex->getHint()); } catch (Exception $ex) { \OCP\Util::logException('index', $ex); diff --git a/lib/private/hintexception.php b/lib/private/hintexception.php index 3934ae2a4c2..3a8361e9e80 100644 --- a/lib/private/hintexception.php +++ b/lib/private/hintexception.php @@ -12,7 +12,7 @@ class HintException extends \Exception { private $hint; - public function __construct($message, $hint = '', $code = 0, Exception $previous = null) { + public function __construct($message, $hint = '', $code = 0, \Exception $previous = null) { $this->hint = $hint; parent::__construct($message, $code, $previous); } diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index 08d0b7d5f93..d257bd12d2a 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -28,7 +28,6 @@ class OC_Log_Owncloud { static protected $logFile; - static protected $reqId; /** * Init class data @@ -69,19 +68,17 @@ class OC_Log_Owncloud { $timezone = new DateTimeZone('UTC'); } $time = new DateTime(null, $timezone); + $reqId = \OC_Request::getRequestID(); + $remoteAddr = \OC_Request::getRemoteAddress(); // remove username/passwords from URLs before writing the to the log file $time = $time->format($format); if($minLevel == OC_Log::DEBUG) { - if(empty(self::$reqId)) { - self::$reqId = uniqid(); - } - $reqId = self::$reqId; $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '--'; $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '--'; - $entry = compact('reqId', 'app', 'message', 'level', 'time', 'method', 'url'); + $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time', 'method', 'url'); } else { - $entry = compact('app', 'message', 'level', 'time'); + $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time'); } $entry = json_encode($entry); $handle = @fopen(self::$logFile, 'a'); diff --git a/lib/private/request.php b/lib/private/request.php index b063c1f5967..fa446837a97 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -14,6 +14,7 @@ class OC_Request { const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#'; const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)(:[0-9]+|)$/'; + static protected $reqId; /** * Returns the remote address, if the connection came from a trusted proxy and `forwarded_for_headers` has been configured @@ -22,7 +23,7 @@ class OC_Request { * @return string IP address */ public static function getRemoteAddress() { - $remoteAddress = $_SERVER['REMOTE_ADDR']; + $remoteAddress = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; $trustedProxies = \OC::$server->getConfig()->getSystemValue('trusted_proxies', array()); if(is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) { @@ -44,6 +45,17 @@ class OC_Request { } /** + * Returns an ID for the request, value is not guaranteed to be unique and is mostly meant for logging + * @return string + */ + public static function getRequestID() { + if(self::$reqId === null) { + self::$reqId = hash('md5', microtime().\OC::$server->getSecureRandom()->getLowStrengthGenerator()->generate(20)); + } + return self::$reqId; + } + + /** * Check overwrite condition * @param string $type * @return bool diff --git a/lib/private/template.php b/lib/private/template.php index d95943a714c..fce26117ede 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -250,8 +250,7 @@ class OC_Template extends \OC\Template\Base { /** * Print a fatal error page and terminates the script * @param string $error_msg The error message to show - * @param string $hint An optional hint message - * Warning: All data passed to $hint needs to get sanitized using OC_Util::sanitizeHTML + * @param string $hint An optional hint message - needs to be properly escaped */ public static function printErrorPage( $error_msg, $hint = '' ) { $content = new \OC_Template( '', 'error', 'error', false ); @@ -266,28 +265,16 @@ class OC_Template extends \OC\Template\Base { * @param Exception $exception */ public static function printExceptionErrorPage(Exception $exception) { - $error_msg = $exception->getMessage(); - if ($exception->getCode()) { - $error_msg = '['.$exception->getCode().'] '.$error_msg; - } - if (defined('DEBUG') and DEBUG) { - $hint = $exception->getTraceAsString(); - if (!empty($hint)) { - $hint = '<pre>'.OC_Util::sanitizeHTML($hint).'</pre>'; - } - while (method_exists($exception, 'previous') && $exception = $exception->previous()) { - $error_msg .= '<br/>Caused by:' . ' '; - if ($exception->getCode()) { - $error_msg .= '['.OC_Util::sanitizeHTML($exception->getCode()).'] '; - } - $error_msg .= OC_Util::sanitizeHTML($exception->getMessage()); - }; - } else { - $hint = ''; - if ($exception instanceof \OC\HintException) { - $hint = OC_Util::sanitizeHTML($exception->getHint()); - } - } - self::printErrorPage($error_msg, $hint); + $content = new \OC_Template('', 'exception', 'error', false); + $content->assign('errorMsg', $exception->getMessage()); + $content->assign('errorCode', $exception->getCode()); + $content->assign('file', $exception->getFile()); + $content->assign('line', $exception->getLine()); + $content->assign('trace', $exception->getTraceAsString()); + $content->assign('debugMode', defined('DEBUG') && DEBUG === true); + $content->assign('remoteAddr', OC_Request::getRemoteAddress()); + $content->assign('requestID', OC_Request::getRequestID()); + $content->printPage(); + die(); } } diff --git a/lib/public/util.php b/lib/public/util.php index 244c11ba2cc..a0118e41cc4 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -82,38 +82,20 @@ class Util { } /** - * write exception into the log. Include the stack trace - * if DEBUG mode is enabled + * write exception into the log * @param string $app app name * @param \Exception $ex exception to log - * @param string $level log level, defaults to \OCP\Util::FATAL + * @param int $level log level, defaults to \OCP\Util::FATAL */ public static function logException( $app, \Exception $ex, $level = \OCP\Util::FATAL ) { - $class = get_class($ex); - $message = $class . ': ' . $ex->getMessage(); - if ($ex->getCode()) { - $message .= ' [' . $ex->getCode() . ']'; - } - \OCP\Util::writeLog($app, $message, $level); - if (defined('DEBUG') and DEBUG) { - // also log stack trace - $stack = explode("\n", $ex->getTraceAsString()); - // first element is empty - array_shift($stack); - foreach ($stack as $s) { - \OCP\Util::writeLog($app, 'Exception: ' . $s, $level); - } - - // include cause - while (method_exists($ex, 'getPrevious') && $ex = $ex->getPrevious()) { - $message .= ' - Caused by:' . ' '; - $message .= $ex->getMessage(); - if ($ex->getCode()) { - $message .= '[' . $ex->getCode() . '] '; - } - \OCP\Util::writeLog($app, 'Exception: ' . $message, $level); - } - } + $exception = array( + 'Message' => $ex->getMessage(), + 'Code' => $ex->getCode(), + 'Trace' => $ex->getTraceAsString(), + 'File' => $ex->getFile(), + 'Line' => $ex->getLine(), + ); + \OCP\Util::writeLog($app, 'Exception: ' . json_encode($exception), $level); } /** |