CVE-2016-9466 (PHP, published 2017-03-28T02:59Z)
Description: value: Nextcloud Server before 10.0.1 & ownCloud Server before 9.0.6 and 9.1.2 suffer from Reflected XSS in the Gallery application. The gallery app was not properly sanitizing exception messages from the Nextcloud/ownCloud server. Due to an endpoint where an attacker could influence the error message, this led to a reflected Cross-Site-Scripting vulnerability.
Severity: MEDIUM (CVSS v3 base score: 6.1)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/nextcloud/gallery
Files changed:
controller/configapicontroller.php
controller/configcontroller.php
controller/filesapicontroller.php
controller/filescontroller.php
controller/httperror.php
js/galleryview.js
tests/unit/controller/ConfigControllerTest.php
tests/unit/controller/FilesControllerTest.php
tests/unit/controller/HttpErrorTest.php
Commit message: Do not display technical error messages


Vulnerable code:
			return $this->jsonError($exception);
			return $this->jsonError($exception);
			return $this->jsonError($exception);
			return $this->jsonError($exception);
	public function jsonError(Exception $exception) {
		$message = $exception->getMessage();
				'message' => $message . ' (' . $code . ')',
				'success' => false
				message += '<p>' + errorMessage + '</p>';
		// Default status code when something breaks
		$status = Http::STATUS_INTERNAL_SERVER_ERROR;
			'message' => $exceptionMessage  . ' (' . $status . ')',
			'message' => $exceptionMessage . ' (' . $status . ')',
		$notFoundEnvMessage = 'Not found in env';
		$notFoundServiceMessage = 'Not found in service';
		$errorServiceMessage = 'Broken service';
		$coreServiceMessage = 'Broken core';
		$httpError = $this->getMockForTrait('\OCA\Gallery\Controller\HttpError');
		$response = $httpError->jsonError($exception);
		$this->assertEquals(
			['message' => $message . ' (' . $status . ')', 'success' => false], $response->getData()

Fixed code:
			return $this->jsonError($exception, $this->request, $this->logger);
			return $this->jsonError($exception, $this->request, $this->logger);
			return $this->jsonError($exception, $this->request, $this->logger);
			return $this->jsonError($exception, $this->request, $this->logger);
use OCP\ILogger;
use OCP\IRequest;
	 * @param IRequest $request
	 * @param ILogger $logger
	public function jsonError(Exception $exception,
							  IRequest $request,
							  ILogger $logger) {
		// If the exception is not of type ForbiddenServiceException only show a
		// generic error message to avoid leaking information.
		if(!($exception instanceof ForbiddenServiceException)) {
			$logger->logException($exception, ['app' => 'gallery']);
			$message = sprintf('An error occurred. Request ID: %s', $request->getId());
		} else {
			$message = $exception->getMessage() . ' (' . $code . ')';
		}

				'message' => $message,
				'success' => false,
				message += '<p>' + escapeHTML(errorMessage) + '</p>';
		$this->request
			->expects($this->once())
			->method('getId')
			->willReturn('1234');
			'message' => 'An error occurred. Request ID: 1234',
		$this->request
			->expects($this->once())
			->method('getId')
			->willReturn('1234');
			'message' => 'An error occurred. Request ID: 1234',
use OCP\ILogger;
use OCP\IRequest;
		$notFoundEnvMessage = 'An error occurred. Request ID: 1234';
		$notFoundServiceMessage = 'An error occurred. Request ID: 1234';
		$errorServiceMessage = 'An error occurred. Request ID: 1234';
		$coreServiceMessage = 'An error occurred. Request ID: 1234';
		$request = $this->createMock(IRequest::class);
		$logger = $this->createMock(ILogger::class);

		if($exception instanceof ForbiddenServiceException) {
			$amount = 0;
			$message = $message . ' (' . $status . ')';
		} else {
			$amount = 1;
		}

		$logger
			->expects($this->exactly($amount))
			->method('logException')
			->with($exception, ['app' => 'gallery']);
		$request
			->expects($this->exactly($amount))
			->method('getId')
			->willReturn('1234');

		/** @var HttpError $httpError */
		$httpError = $this->getMockForTrait(HttpError::class);
		$response = $httpError->jsonError($exception, $request, $logger);
		$this->assertSame(
			['message' => $message, 'success' => false], $response->getData()