Skip to content

Commit

Permalink
fix: Re-throwing the TypeError to prevent exposing the installation path
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Kesselberg <[email protected]>
  • Loading branch information
kesselb committed Nov 28, 2024
1 parent f8bb373 commit 51b6b9a
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 1 deletion.
90 changes: 90 additions & 0 deletions apps/dav/lib/Connector/Sabre/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
*/
namespace OCA\DAV\Connector\Sabre;

use Sabre\DAV\Exception;
use Sabre\DAV\Version;

/**
* Class \OCA\DAV\Connector\Sabre\Server
*
Expand All @@ -25,4 +28,91 @@ public function __construct($treeOrNode = null) {
self::$exposeVersion = false;
$this->enablePropfindDepthInfinity = true;
}

/**
*
* @return void
*/
public function start() {
try {
// If nginx (pre-1.2) is used as a proxy server, and SabreDAV as an
// origin, we must make sure we send back HTTP/1.0 if this was
// requested.
// This is mainly because nginx doesn't support Chunked Transfer
// Encoding, and this forces the webserver SabreDAV is running on,
// to buffer entire responses to calculate Content-Length.
$this->httpResponse->setHTTPVersion($this->httpRequest->getHTTPVersion());

// Setting the base url
$this->httpRequest->setBaseUrl($this->getBaseUri());
$this->invokeMethod($this->httpRequest, $this->httpResponse);
} catch (\Error $e) {
/*
* The TypeError includes the file path where the error occurred,
* potentially revealing the installation directory.
*
* By re-throwing the exception, we ensure that the
* default exception handler processes it.
*/
throw $e;
} catch (\Throwable $e) {
try {
$this->emit('exception', [$e]);
} catch (\Exception $ignore) {
}

$DOM = new \DOMDocument('1.0', 'utf-8');
$DOM->formatOutput = true;

$error = $DOM->createElementNS('DAV:', 'd:error');
$error->setAttribute('xmlns:s', self::NS_SABREDAV);
$DOM->appendChild($error);

$h = function ($v) {

Check notice

Code scanning / Psalm

MissingClosureReturnType Note

Closure does not have a return type, expecting string

Check notice

Code scanning / Psalm

MissingClosureParamType Note

Parameter $v has no provided type
return htmlspecialchars((string)$v, ENT_NOQUOTES, 'UTF-8');
};

if (self::$exposeVersion) {
$error->appendChild($DOM->createElement('s:sabredav-version', $h(Version::VERSION)));
}

$error->appendChild($DOM->createElement('s:exception', $h(get_class($e))));
$error->appendChild($DOM->createElement('s:message', $h($e->getMessage())));
if ($this->debugExceptions) {
$error->appendChild($DOM->createElement('s:file', $h($e->getFile())));
$error->appendChild($DOM->createElement('s:line', $h($e->getLine())));
$error->appendChild($DOM->createElement('s:code', $h($e->getCode())));
$error->appendChild($DOM->createElement('s:stacktrace', $h($e->getTraceAsString())));
}

if ($this->debugExceptions) {
$previous = $e;

Check notice

Code scanning / Psalm

MissingClosureReturnType Note

Closure does not have a return type, expecting string

Check notice

Code scanning / Psalm

MissingClosureParamType Note

Parameter $v has no provided type
while ($previous = $previous->getPrevious()) {
$xPrevious = $DOM->createElement('s:previous-exception');
$xPrevious->appendChild($DOM->createElement('s:exception', $h(get_class($previous))));
$xPrevious->appendChild($DOM->createElement('s:message', $h($previous->getMessage())));
$xPrevious->appendChild($DOM->createElement('s:file', $h($previous->getFile())));
$xPrevious->appendChild($DOM->createElement('s:line', $h($previous->getLine())));
$xPrevious->appendChild($DOM->createElement('s:code', $h($previous->getCode())));
$xPrevious->appendChild($DOM->createElement('s:stacktrace', $h($previous->getTraceAsString())));
$error->appendChild($xPrevious);
}
}

if ($e instanceof Exception) {
$httpCode = $e->getHTTPCode();
$e->serialize($this, $error);
$headers = $e->getHTTPHeaders($this);
} else {
$httpCode = 500;
$headers = [];
}
$headers['Content-Type'] = 'application/xml; charset=utf-8';

$this->httpResponse->setStatus($httpCode);
$this->httpResponse->setHeaders($headers);
$this->httpResponse->setBody($DOM->saveXML());
$this->sapi->sendResponse($this->httpResponse);
}
}
}
3 changes: 2 additions & 1 deletion remote.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ class RemoteException extends \Exception {
function handleException($e) {
try {
$request = \OC::$server->getRequest();
$isError = $e instanceof Error;
// in case the request content type is text/xml - we assume it's a WebDAV request
$isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml');
if ($isXmlContentType === 0) {
if ($isError === false && $isXmlContentType === 0) {
// fire up a simple server to properly process the exception
$server = new Server();
if (!($e instanceof RemoteException)) {
Expand Down

0 comments on commit 51b6b9a

Please sign in to comment.