Index: trunk/phase3/skins/Standard.php |
— | — | @@ -18,10 +18,10 @@ |
19 | 19 | /** |
20 | 20 | * |
21 | 21 | */ |
22 | | - function getHeadScripts() { |
| 22 | + function getHeadScripts( $allowUserJs ) { |
23 | 23 | global $wgStylePath, $wgJsMimeType, $wgStyleVersion; |
24 | 24 | |
25 | | - $s = parent::getHeadScripts(); |
| 25 | + $s = parent::getHeadScripts( $allowUserJs ); |
26 | 26 | if ( 3 == $this->qbSetting() ) { # Floating left |
27 | 27 | $s .= "<script language='javascript' type='$wgJsMimeType' " . |
28 | 28 | "src='{$wgStylePath}/common/sticky.js?$wgStyleVersion'></script>\n"; |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -15,6 +15,7 @@ |
16 | 16 | var $mLastModified, $mETag, $mCategoryLinks; |
17 | 17 | var $mScripts, $mLinkColours, $mPageLinkTitle; |
18 | 18 | |
| 19 | + var $mAllowUserJs; |
19 | 20 | var $mSuppressQuickbar; |
20 | 21 | var $mOnloadHandler; |
21 | 22 | var $mDoNothing; |
— | — | @@ -33,6 +34,8 @@ |
34 | 35 | * Initialise private variables |
35 | 36 | */ |
36 | 37 | function __construct() { |
| 38 | + global $wgAllowUserJs; |
| 39 | + $this->mAllowUserJs = $wgAllowUserJs; |
37 | 40 | $this->mMetatags = $this->mKeywords = $this->mLinktags = array(); |
38 | 41 | $this->mHTMLtitle = $this->mPagetitle = $this->mBodytext = |
39 | 42 | $this->mRedirect = $this->mLastModified = |
— | — | @@ -283,6 +286,9 @@ |
284 | 287 | public function suppressQuickbar() { $this->mSuppressQuickbar = true; } |
285 | 288 | public function isQuickbarSuppressed() { return $this->mSuppressQuickbar; } |
286 | 289 | |
| 290 | + public function disallowUserJs() { $this->mAllowUserJs = false; } |
| 291 | + public function isUserJsAllowed() { return $this->mAllowUserJs; } |
| 292 | + |
287 | 293 | public function addHTML( $text ) { $this->mBodytext .= $text; } |
288 | 294 | public function clearHTML() { $this->mBodytext = ''; } |
289 | 295 | public function getHTML() { return $this->mBodytext; } |
— | — | @@ -1138,7 +1144,7 @@ |
1139 | 1145 | $ret .= "<link rel='stylesheet' type='text/css' $media href='$printsheet' />\n"; |
1140 | 1146 | |
1141 | 1147 | $sk = $wgUser->getSkin(); |
1142 | | - $ret .= $sk->getHeadScripts(); |
| 1148 | + $ret .= $sk->getHeadScripts( $this->mAllowUserJs ); |
1143 | 1149 | $ret .= $this->mScripts; |
1144 | 1150 | $ret .= $sk->getUserStyles(); |
1145 | 1151 | $ret .= $this->getHeadItems(); |
Index: trunk/phase3/includes/SkinTemplate.php |
— | — | @@ -179,7 +179,7 @@ |
180 | 180 | |
181 | 181 | $this->usercss = $this->userjs = $this->userjsprev = false; |
182 | 182 | $this->setupUserCss(); |
183 | | - $this->setupUserJs(); |
| 183 | + $this->setupUserJs( $out->isUserJsAllowed() ); |
184 | 184 | $this->titletxt = $this->mTitle->getPrefixedText(); |
185 | 185 | wfProfileOut( "$fname-stuff" ); |
186 | 186 | |
— | — | @@ -984,14 +984,14 @@ |
985 | 985 | /** |
986 | 986 | * @private |
987 | 987 | */ |
988 | | - function setupUserJs() { |
| 988 | + function setupUserJs( $allowUserJs ) { |
989 | 989 | $fname = 'SkinTemplate::setupUserJs'; |
990 | 990 | wfProfileIn( $fname ); |
991 | 991 | |
992 | | - global $wgRequest, $wgAllowUserJs, $wgJsMimeType; |
| 992 | + global $wgRequest, $wgJsMimeType; |
993 | 993 | $action = $wgRequest->getText('action'); |
994 | 994 | |
995 | | - if( $wgAllowUserJs && $this->loggedin ) { |
| 995 | + if( $allowUserJs && $this->loggedin ) { |
996 | 996 | if( $this->mTitle->isJsSubpage() and $this->userCanPreview( $action ) ) { |
997 | 997 | # XXX: additional security check/prompt? |
998 | 998 | $this->userjsprev = '/*<![CDATA[*/ ' . $wgRequest->getText('wpTextbox1') . ' /*]]>*/'; |
Index: trunk/phase3/includes/SpecialPreferences.php |
— | — | @@ -496,6 +496,8 @@ |
497 | 497 | $wgOut->setArticleRelated( false ); |
498 | 498 | $wgOut->setRobotpolicy( 'noindex,nofollow' ); |
499 | 499 | |
| 500 | + $wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc. |
| 501 | + |
500 | 502 | if ( $this->mSuccess || 'success' == $status ) { |
501 | 503 | $wgOut->addWikitext( '<div class="successbox"><strong>'. wfMsg( 'savedprefs' ) . '</strong></div>' ); |
502 | 504 | } else if ( 'error' == $status ) { |
Index: trunk/phase3/includes/Skin.php |
— | — | @@ -334,8 +334,8 @@ |
335 | 335 | return self::makeVariablesScript( $vars ); |
336 | 336 | } |
337 | 337 | |
338 | | - function getHeadScripts() { |
339 | | - global $wgStylePath, $wgUser, $wgAllowUserJs, $wgJsMimeType, $wgStyleVersion; |
| 338 | + function getHeadScripts( $allowUserJs ) { |
| 339 | + global $wgStylePath, $wgUser, $wgJsMimeType, $wgStyleVersion; |
340 | 340 | |
341 | 341 | $r = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) ); |
342 | 342 | |
— | — | @@ -348,7 +348,7 @@ |
349 | 349 | $r .= "<script type=\"$wgJsMimeType\" src=\"".htmlspecialchars(self::makeUrl('-','action=raw&gen=js'))."\"><!-- site js --></script>\n"; |
350 | 350 | } |
351 | 351 | } |
352 | | - if( $wgAllowUserJs && $wgUser->isLoggedIn() ) { |
| 352 | + if( $allowUserJs && $wgUser->isLoggedIn() ) { |
353 | 353 | $userpage = $wgUser->getUserPage(); |
354 | 354 | $userjs = htmlspecialchars( self::makeUrl( |
355 | 355 | $userpage->getPrefixedText().'/'.$this->getSkinName().'.js', |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -40,6 +40,8 @@ |
41 | 41 | like [[User:#123|#123]] |
42 | 42 | * Use the standard HTTP fetch functions when retrieving remote wiki pages |
43 | 43 | 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. |
44 | 46 | |
45 | 47 | == Maintenance script changes since 1.10 == |
46 | 48 | |