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.)
This commit is contained in:
parent
360c62aca6
commit
183818b0a7
6 changed files with 20 additions and 10 deletions
|
|
@ -40,6 +40,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
|
|||
like [[User:#123|#123]]
|
||||
* Use the standard HTTP fetch functions when retrieving remote wiki pages
|
||||
through transwiki, so we can take advantage of cURL goodies if available
|
||||
* Disable custom user javascript in Special:Preferences, to avoid the risk
|
||||
of a compromised script sniffing passwords etc.
|
||||
|
||||
== Maintenance script changes since 1.10 ==
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class OutputPage {
|
|||
var $mLastModified, $mETag, $mCategoryLinks;
|
||||
var $mScripts, $mLinkColours, $mPageLinkTitle;
|
||||
|
||||
var $mAllowUserJs;
|
||||
var $mSuppressQuickbar;
|
||||
var $mOnloadHandler;
|
||||
var $mDoNothing;
|
||||
|
|
@ -33,6 +34,8 @@ class OutputPage {
|
|||
* Initialise private variables
|
||||
*/
|
||||
function __construct() {
|
||||
global $wgAllowUserJs;
|
||||
$this->mAllowUserJs = $wgAllowUserJs;
|
||||
$this->mMetatags = $this->mKeywords = $this->mLinktags = array();
|
||||
$this->mHTMLtitle = $this->mPagetitle = $this->mBodytext =
|
||||
$this->mRedirect = $this->mLastModified =
|
||||
|
|
@ -283,6 +286,9 @@ class OutputPage {
|
|||
public function suppressQuickbar() { $this->mSuppressQuickbar = true; }
|
||||
public function isQuickbarSuppressed() { return $this->mSuppressQuickbar; }
|
||||
|
||||
public function disallowUserJs() { $this->mAllowUserJs = false; }
|
||||
public function isUserJsAllowed() { return $this->mAllowUserJs; }
|
||||
|
||||
public function addHTML( $text ) { $this->mBodytext .= $text; }
|
||||
public function clearHTML() { $this->mBodytext = ''; }
|
||||
public function getHTML() { return $this->mBodytext; }
|
||||
|
|
@ -1138,7 +1144,7 @@ class OutputPage {
|
|||
$ret .= "<link rel='stylesheet' type='text/css' $media href='$printsheet' />\n";
|
||||
|
||||
$sk = $wgUser->getSkin();
|
||||
$ret .= $sk->getHeadScripts();
|
||||
$ret .= $sk->getHeadScripts( $this->mAllowUserJs );
|
||||
$ret .= $this->mScripts;
|
||||
$ret .= $sk->getUserStyles();
|
||||
$ret .= $this->getHeadItems();
|
||||
|
|
|
|||
|
|
@ -334,8 +334,8 @@ class Skin extends Linker {
|
|||
return self::makeVariablesScript( $vars );
|
||||
}
|
||||
|
||||
function getHeadScripts() {
|
||||
global $wgStylePath, $wgUser, $wgAllowUserJs, $wgJsMimeType, $wgStyleVersion;
|
||||
function getHeadScripts( $allowUserJs ) {
|
||||
global $wgStylePath, $wgUser, $wgJsMimeType, $wgStyleVersion;
|
||||
|
||||
$r = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) );
|
||||
|
||||
|
|
@ -348,7 +348,7 @@ class Skin extends Linker {
|
|||
$r .= "<script type=\"$wgJsMimeType\" src=\"".htmlspecialchars(self::makeUrl('-','action=raw&gen=js'))."\"><!-- site js --></script>\n";
|
||||
}
|
||||
}
|
||||
if( $wgAllowUserJs && $wgUser->isLoggedIn() ) {
|
||||
if( $allowUserJs && $wgUser->isLoggedIn() ) {
|
||||
$userpage = $wgUser->getUserPage();
|
||||
$userjs = htmlspecialchars( self::makeUrl(
|
||||
$userpage->getPrefixedText().'/'.$this->getSkinName().'.js',
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ class SkinTemplate extends Skin {
|
|||
|
||||
$this->usercss = $this->userjs = $this->userjsprev = false;
|
||||
$this->setupUserCss();
|
||||
$this->setupUserJs();
|
||||
$this->setupUserJs( $out->isUserJsAllowed() );
|
||||
$this->titletxt = $this->mTitle->getPrefixedText();
|
||||
wfProfileOut( "$fname-stuff" );
|
||||
|
||||
|
|
@ -984,14 +984,14 @@ class SkinTemplate extends Skin {
|
|||
/**
|
||||
* @private
|
||||
*/
|
||||
function setupUserJs() {
|
||||
function setupUserJs( $allowUserJs ) {
|
||||
$fname = 'SkinTemplate::setupUserJs';
|
||||
wfProfileIn( $fname );
|
||||
|
||||
global $wgRequest, $wgAllowUserJs, $wgJsMimeType;
|
||||
global $wgRequest, $wgJsMimeType;
|
||||
$action = $wgRequest->getText('action');
|
||||
|
||||
if( $wgAllowUserJs && $this->loggedin ) {
|
||||
if( $allowUserJs && $this->loggedin ) {
|
||||
if( $this->mTitle->isJsSubpage() and $this->userCanPreview( $action ) ) {
|
||||
# XXX: additional security check/prompt?
|
||||
$this->userjsprev = '/*<![CDATA[*/ ' . $wgRequest->getText('wpTextbox1') . ' /*]]>*/';
|
||||
|
|
|
|||
|
|
@ -496,6 +496,8 @@ class PreferencesForm {
|
|||
$wgOut->setArticleRelated( false );
|
||||
$wgOut->setRobotpolicy( 'noindex,nofollow' );
|
||||
|
||||
$wgOut->disallowUserJs(); # Prevent hijacked user scripts from sniffing passwords etc.
|
||||
|
||||
if ( $this->mSuccess || 'success' == $status ) {
|
||||
$wgOut->addWikitext( '<div class="successbox"><strong>'. wfMsg( 'savedprefs' ) . '</strong></div>' );
|
||||
} else if ( 'error' == $status ) {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ class SkinStandard extends Skin {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
function getHeadScripts() {
|
||||
function getHeadScripts( $allowUserJs ) {
|
||||
global $wgStylePath, $wgJsMimeType, $wgStyleVersion;
|
||||
|
||||
$s = parent::getHeadScripts();
|
||||
$s = parent::getHeadScripts( $allowUserJs );
|
||||
if ( 3 == $this->qbSetting() ) { # Floating left
|
||||
$s .= "<script language='javascript' type='$wgJsMimeType' " .
|
||||
"src='{$wgStylePath}/common/sticky.js?$wgStyleVersion'></script>\n";
|
||||
|
|
|
|||
Loading…
Reference in a new issue