r22008 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r22007‎ | r22008 | r22009 >
Date:20:48, 8 May 2007
Author:vyznev
Status:old
Tags:
Comment:
Disable user scripts on Special:Preferences, to prevent a compromised
script from being able to sniff passwords etc.

(The control flow here is hopelessly tangled between OutputPage and
the skins, and it doesn't help that Skin and SkinTemplate do things
differently for no particular reason. I haven't made any attempt to
untangle it in this commit, but hopefully I at least haven't made it
too much worse. Cleanup is welcome.)
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/OutputPage.php (modified) (history)
  • /trunk/phase3/includes/Skin.php (modified) (history)
  • /trunk/phase3/includes/SkinTemplate.php (modified) (history)
  • /trunk/phase3/includes/SpecialPreferences.php (modified) (history)
  • /trunk/phase3/skins/Standard.php (modified) (history)

Diff [purge]

Index: trunk/phase3/skins/Standard.php
@@ -18,10 +18,10 @@
1919 /**
2020 *
2121 */
22 - function getHeadScripts() {
 22+ function getHeadScripts( $allowUserJs ) {
2323 global $wgStylePath, $wgJsMimeType, $wgStyleVersion;
2424
25 - $s = parent::getHeadScripts();
 25+ $s = parent::getHeadScripts( $allowUserJs );
2626 if ( 3 == $this->qbSetting() ) { # Floating left
2727 $s .= "<script language='javascript' type='$wgJsMimeType' " .
2828 "src='{$wgStylePath}/common/sticky.js?$wgStyleVersion'></script>\n";
Index: trunk/phase3/includes/OutputPage.php
@@ -15,6 +15,7 @@
1616 var $mLastModified, $mETag, $mCategoryLinks;
1717 var $mScripts, $mLinkColours, $mPageLinkTitle;
1818
 19+ var $mAllowUserJs;
1920 var $mSuppressQuickbar;
2021 var $mOnloadHandler;
2122 var $mDoNothing;
@@ -33,6 +34,8 @@
3435 * Initialise private variables
3536 */
3637 function __construct() {
 38+ global $wgAllowUserJs;
 39+ $this->mAllowUserJs = $wgAllowUserJs;
3740 $this->mMetatags = $this->mKeywords = $this->mLinktags = array();
3841 $this->mHTMLtitle = $this->mPagetitle = $this->mBodytext =
3942 $this->mRedirect = $this->mLastModified =
@@ -283,6 +286,9 @@
284287 public function suppressQuickbar() { $this->mSuppressQuickbar = true; }
285288 public function isQuickbarSuppressed() { return $this->mSuppressQuickbar; }
286289
 290+ public function disallowUserJs() { $this->mAllowUserJs = false; }
 291+ public function isUserJsAllowed() { return $this->mAllowUserJs; }
 292+
287293 public function addHTML( $text ) { $this->mBodytext .= $text; }
288294 public function clearHTML() { $this->mBodytext = ''; }
289295 public function getHTML() { return $this->mBodytext; }
@@ -1138,7 +1144,7 @@
11391145 $ret .= "<link rel='stylesheet' type='text/css' $media href='$printsheet' />\n";
11401146
11411147 $sk = $wgUser->getSkin();
1142 - $ret .= $sk->getHeadScripts();
 1148+ $ret .= $sk->getHeadScripts( $this->mAllowUserJs );
11431149 $ret .= $this->mScripts;
11441150 $ret .= $sk->getUserStyles();
11451151 $ret .= $this->getHeadItems();
Index: trunk/phase3/includes/SkinTemplate.php
@@ -179,7 +179,7 @@
180180
181181 $this->usercss = $this->userjs = $this->userjsprev = false;
182182 $this->setupUserCss();
183 - $this->setupUserJs();
 183+ $this->setupUserJs( $out->isUserJsAllowed() );
184184 $this->titletxt = $this->mTitle->getPrefixedText();
185185 wfProfileOut( "$fname-stuff" );
186186
@@ -984,14 +984,14 @@
985985 /**
986986 * @private
987987 */
988 - function setupUserJs() {
 988+ function setupUserJs( $allowUserJs ) {
989989 $fname = 'SkinTemplate::setupUserJs';
990990 wfProfileIn( $fname );
991991
992 - global $wgRequest, $wgAllowUserJs, $wgJsMimeType;
 992+ global $wgRequest, $wgJsMimeType;
993993 $action = $wgRequest->getText('action');
994994
995 - if( $wgAllowUserJs && $this->loggedin ) {
 995+ if( $allowUserJs && $this->loggedin ) {
996996 if( $this->mTitle->isJsSubpage() and $this->userCanPreview( $action ) ) {
997997 # XXX: additional security check/prompt?
998998 $this->userjsprev = '/*<![CDATA[*/ ' . $wgRequest->getText('wpTextbox1') . ' /*]]>*/';
Index: trunk/phase3/includes/SpecialPreferences.php
@@ -496,6 +496,8 @@
497497 $wgOut->setArticleRelated( false );
498498 $wgOut->setRobotpolicy( 'noindex,nofollow' );
499499
 500+ $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
 501+
500502 if ( $this->mSuccess || 'success' == $status ) {
501503 $wgOut->addWikitext( '<div class="successbox"><strong>'. wfMsg( 'savedprefs' ) . '</strong></div>' );
502504 } else if ( 'error' == $status ) {
Index: trunk/phase3/includes/Skin.php
@@ -334,8 +334,8 @@
335335 return self::makeVariablesScript( $vars );
336336 }
337337
338 - function getHeadScripts() {
339 - global $wgStylePath, $wgUser, $wgAllowUserJs, $wgJsMimeType, $wgStyleVersion;
 338+ function getHeadScripts( $allowUserJs ) {
 339+ global $wgStylePath, $wgUser, $wgJsMimeType, $wgStyleVersion;
340340
341341 $r = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) );
342342
@@ -348,7 +348,7 @@
349349 $r .= "<script type=\"$wgJsMimeType\" src=\"".htmlspecialchars(self::makeUrl('-','action=raw&gen=js'))."\"><!-- site js --></script>\n";
350350 }
351351 }
352 - if( $wgAllowUserJs && $wgUser->isLoggedIn() ) {
 352+ if( $allowUserJs && $wgUser->isLoggedIn() ) {
353353 $userpage = $wgUser->getUserPage();
354354 $userjs = htmlspecialchars( self::makeUrl(
355355 $userpage->getPrefixedText().'/'.$this->getSkinName().'.js',
Index: trunk/phase3/RELEASE-NOTES
@@ -40,6 +40,8 @@
4141 like [[User:#123|#123]]
4242 * Use the standard HTTP fetch functions when retrieving remote wiki pages
4343 through transwiki, so we can take advantage of cURL goodies if available
 44+* Disable custom user javascript in Special:Preferences, to avoid the risk
 45+ of a compromised script sniffing passwords etc.
4446
4547 == Maintenance script changes since 1.10 ==
4648