Krinkle has uploaded a new change for review. https://gerrit.wikimedia.org/r/217970
Change subject: Page: Fix redirect for page index urls without trailing slash ...................................................................... Page: Fix redirect for page index urls without trailing slash Since DirectorySlash was recently disabled (due to non-HTTPS redirects), the script now sometimes sees urls without the trailing slash. Without this, urls like https://doc.wikimedia.org/Flow redirect to https://doc.wikimedia.org/master/ instead of https://doc.wikimedia.org/Flow/master/ Change-Id: If9fde1792a8cf6f49ea84f51004a1ac780b9bfa7 --- M shared/Page.php 1 file changed, 16 insertions(+), 4 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/integration/docroot refs/changes/70/217970/1 diff --git a/shared/Page.php b/shared/Page.php index 38c3bd9..a99120e 100644 --- a/shared/Page.php +++ b/shared/Page.php @@ -26,6 +26,7 @@ */ protected $rootDir = false; protected $dir = false; + protected $originalPath; protected $flags = 0; protected $libPath = false; @@ -277,14 +278,17 @@ if ( !$path || !isset( $_SERVER['DOCUMENT_ROOT'] ) ) { Page::error( 'Invalid context.' ); } - $path = realpath( $_SERVER['DOCUMENT_ROOT'] . $path ); - if ( !$path || strpos( $path, $_SERVER['DOCUMENT_ROOT'] ) !== 0 ) { + // Use realpath() to prevent escalation through e.g. "../" + // Note: realpath() also normalses paths to have no trailing slash + $realPath = realpath( $_SERVER['DOCUMENT_ROOT'] . $path ); + if ( !$realPath || strpos( $realPath, $_SERVER['DOCUMENT_ROOT'] ) !== 0 ) { // Path escalation. Should be impossible as Apache normalises this. Page::error( 'Invalid context.' ); } $p = self::newFromPageName( $pageName, $flags ); - $p->setDir( $path ); + $p->originalPath = $path; + $p->setDir( $realPath ); return $p; } @@ -299,7 +303,15 @@ $subDirPaths = glob( "{$this->dir}/*", GLOB_ONLYDIR ); if ( $this->flags & self::INDEX_ALLOW_SKIP ) { if ( count( $subDirPaths ) === 1 ) { - header( 'Location: ./' . basename( $subDirPaths[0] ) . '/' ); + // Check whether the request URI ends in a slash and redirect to /a/b/c/target + // as either ./target/ or ./c/target/. Redirects from requests no trailing slash + // would otherwise end up at /a/b/target/. + if ( substr( $this->originalPath, -1 ) === '/' ) { + $target = './' . basename( $subDirPaths[0] ) . '/'; + } else { + $target = './' . basename( $this->originalPath ) . '/' . basename( $subDirPaths[0] ) . '/'; + } + header( "Location: $target" ); exit; } } -- To view, visit https://gerrit.wikimedia.org/r/217970 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If9fde1792a8cf6f49ea84f51004a1ac780b9bfa7 Gerrit-PatchSet: 1 Gerrit-Project: integration/docroot Gerrit-Branch: master Gerrit-Owner: Krinkle <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
