Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F2879417
sec-redir2.patch
Bawolff (Brian Wolff)
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Authored By
Bawolff
Oct 27 2015, 3:24 AM
2015-10-27 03:24:17 (UTC+0)
Size
7 KB
Referenced Files
None
Subscribers
None
sec-redir2.patch
View Options
From 717544b5880730fbcfaec000563915370c32c4ee Mon Sep 17 00:00:00 2001
From: csteipp <csteipp@wikimedia.org>
Date: Mon, 5 Oct 2015 16:58:42 -0700
Subject: [PATCH] SECURITY: Make Special:MyPage and friends fake redirect to
prevent info leak
This prevents a malicious person from using external resources on their
website to cause the victim's web browser to load
Special:MyPage -> User:Username, and then looking it up in the page hit
statistics in order to correlate IPs from the malicious person's server
log, with usernames on wiki.
This feature can be disabled with $wgHideIdentifiableRedirects.
Bug: T109724
Change-Id: Ia0e742dc92c77af4832174dfa24c6dcaa6ee80e9
---
includes/DefaultSettings.php | 6 ++++
includes/MediaWiki.php | 44 ++++++++++++++++++++----
includes/specialpage/RedirectSpecialPage.php | 12 +++++++
includes/specials/SpecialMyLanguage.php | 11 ++++++
includes/specials/SpecialMyRedirectPages.php | 50 ++++++++++++++++++++++++++++
5 files changed, 117 insertions(+), 6 deletions(-)
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 910c121..e4e77c7 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -4718,6 +4718,12 @@ $wgWhitelistReadRegexp = false;
$wgEmailConfirmToEdit = false;
/**
+ * Should MediaWiki attempt to protect user's privacy when doing redirects?
+ * Keep this true if access counts to articles are made public.
+ */
+$wgHideIdentifiableRedirects = true;
+
+/**
* Permission keys given to users in each group.
*
* This is an array where the keys are all groups and each value is an
diff --git a/includes/MediaWiki.php b/includes/MediaWiki.php
index 676108c..0a9df4b 100644
--- a/includes/MediaWiki.php
+++ b/includes/MediaWiki.php
@@ -37,6 +37,11 @@ class MediaWiki {
private $config;
/**
+ * @var String Cache what action this request is
+ */
+ private $action;
+
+ /**
* @param IContextSource|null $context
*/
public function __construct( IContextSource $context = null ) {
@@ -141,13 +146,11 @@ class MediaWiki {
* @return string Action
*/
public function getAction() {
- static $action = null;
-
- if ( $action === null ) {
- $action = Action::getActionName( $this->context );
+ if ( $this->action === null ) {
+ $this->action = Action::getActionName( $this->context );
}
- return $action;
+ return $this->action;
}
/**
@@ -241,8 +244,37 @@ class MediaWiki {
// Handle any other redirects.
// Redirect loops, titleless URL, $wgUsePathInfo URLs, and URLs with a variant
} elseif ( !$this->tryNormaliseRedirect( $title ) ) {
+ // Prevent information leak via Special:MyPage et al (T109724)
+ if ( $title->isSpecialPage() ) {
+ $specialPage = SpecialPageFactory::getPage( $title->getDBKey() );
+ if ( $specialPage instanceof RedirectSpecialPage
+ && $this->config->get( 'HideIdentifiableRedirects' )
+ && $specialPage->personallyIdentifiableTarget()
+ ) {
+ list( , $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBKey() );
+ $target = $specialPage->getRedirect( $subpage );
+ // target can also be true. We let that case fall through to normal processing.
+ if ( $target instanceof Title ) {
+ $query = $specialPage->getRedirectQuery() ?: array();
+ $request = new DerivativeRequest( $this->context->getRequest(), $query );
+ $request->setRequestURL( $this->context->getRequest()->getRequestURL() );
+ $this->context->setRequest( $request );
+ // Do not varnish cache these. May vary even for anons
+ $this->context->getOutput()->lowerCdnMaxage( 0 );
+ $this->context->setTitle( $target );
+ $wgTitle = $target;
+ // Reset action type cache. (Special pages have only view)
+ $this->action = null;
+ $title = $target;
+ $output->addJsConfigVars( array(
+ 'wgInternalRedirectTargetUrl' => $target->getFullURL(),
+ ) );
+ $output->addModules( 'mediawiki.action.view.redirect' );
+ }
+ }
+ }
- // Special pages
+ // Special pages ($title may have changed since if statement above)
if ( NS_SPECIAL == $title->getNamespace() ) {
// Actions that need to be made when we have a special pages
SpecialPageFactory::executePath( $title, $this->context );
diff --git a/includes/specialpage/RedirectSpecialPage.php b/includes/specialpage/RedirectSpecialPage.php
index 9129ee5..5047354 100644
--- a/includes/specialpage/RedirectSpecialPage.php
+++ b/includes/specialpage/RedirectSpecialPage.php
@@ -94,6 +94,18 @@ abstract class RedirectSpecialPage extends UnlistedSpecialPage {
? $params
: false;
}
+
+ /**
+ * Indicate if the target of this redirect can be used to identify
+ * a particular user of this wiki (e.g., if the redirect is to the
+ * user page of a User). See T109724.
+ *
+ * @since 1.27
+ * @return bool
+ */
+ public function personallyIdentifiableTarget() {
+ return false;
+ }
}
/**
diff --git a/includes/specials/SpecialMyLanguage.php b/includes/specials/SpecialMyLanguage.php
index 3d8ff97..d11fbe6 100644
--- a/includes/specials/SpecialMyLanguage.php
+++ b/includes/specials/SpecialMyLanguage.php
@@ -99,4 +99,15 @@ class SpecialMyLanguage extends RedirectSpecialArticle {
return $base;
}
}
+
+ /**
+ * Target can identify a specific user's language preference.
+ *
+ * @see T109724
+ * @since 1.27
+ * @return bool
+ */
+ public function personallyIdentifiableTarget() {
+ return true;
+ }
}
diff --git a/includes/specials/SpecialMyRedirectPages.php b/includes/specials/SpecialMyRedirectPages.php
index 5ef03f1..850b1f6 100644
--- a/includes/specials/SpecialMyRedirectPages.php
+++ b/includes/specials/SpecialMyRedirectPages.php
@@ -45,6 +45,16 @@ class SpecialMypage extends RedirectSpecialArticle {
return Title::makeTitle( NS_USER, $this->getUser()->getName() . '/' . $subpage );
}
+
+ /**
+ * Target identifies a specific User. See T109724.
+ *
+ * @since 1.27
+ * @return bool
+ */
+ public function personallyIdentifiableTarget() {
+ return true;
+ }
}
/**
@@ -68,6 +78,16 @@ class SpecialMytalk extends RedirectSpecialArticle {
return Title::makeTitle( NS_USER_TALK, $this->getUser()->getName() . '/' . $subpage );
}
+
+ /**
+ * Target identifies a specific User. See T109724.
+ *
+ * @since 1.27
+ * @return bool
+ */
+ public function personallyIdentifiableTarget() {
+ return true;
+ }
}
/**
@@ -90,6 +110,16 @@ class SpecialMycontributions extends RedirectSpecialPage {
public function getRedirect( $subpage ) {
return SpecialPage::getTitleFor( 'Contributions', $this->getUser()->getName() );
}
+
+ /**
+ * Target identifies a specific User. See T109724.
+ *
+ * @since 1.27
+ * @return bool
+ */
+ public function personallyIdentifiableTarget() {
+ return true;
+ }
}
/**
@@ -110,6 +140,16 @@ class SpecialMyuploads extends RedirectSpecialPage {
public function getRedirect( $subpage ) {
return SpecialPage::getTitleFor( 'Listfiles', $this->getUser()->getName() );
}
+
+ /**
+ * Target identifies a specific User. See T109724.
+ *
+ * @since 1.27
+ * @return bool
+ */
+ public function personallyIdentifiableTarget() {
+ return true;
+ }
}
/**
@@ -132,4 +172,14 @@ class SpecialAllMyUploads extends RedirectSpecialPage {
return SpecialPage::getTitleFor( 'Listfiles', $this->getUser()->getName() );
}
+
+ /**
+ * Target identifies a specific User. See T109724.
+ *
+ * @since 1.27
+ * @return bool
+ */
+ public function personallyIdentifiableTarget() {
+ return true;
+ }
}
--
2.0.1
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2891056
Default Alt Text
sec-redir2.patch (7 KB)
Attached To
Mode
T109724: A combination of Special:MyPage redirects and pagecounts allows an external site to know the wikipedia login of an user
Attached
Detach File
Event Timeline
Log In to Comment