r7358 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r7357‎ | r7358 | r7359 >
Date:06:20, 4 February 2005
Author:vibber
Status:old
Tags:
Comment:
Bump to 1.4beta6. Security tweaks:
* Leave user CSS/JS off by default
* Tighten user CSS/JS preview activation
* Require logged-in edits to include an extra session credential
* ogg removed from default upload whitelist
Modified paths:
  • /branches/REL1_4/phase3/RELEASE-NOTES (modified) (history)
  • /branches/REL1_4/phase3/includes/DefaultSettings.php (modified) (history)
  • /branches/REL1_4/phase3/includes/EditPage.php (modified) (history)
  • /branches/REL1_4/phase3/includes/Skin.php (modified) (history)
  • /branches/REL1_4/phase3/includes/SkinTemplate.php (modified) (history)
  • /branches/REL1_4/phase3/includes/User.php (modified) (history)

Diff [purge]

Index: branches/REL1_4/phase3/includes/User.php
@@ -1079,6 +1079,39 @@
10801080 }
10811081 return false;
10821082 }
 1083+
 1084+ /**
 1085+ * Initialize (if necessary) and return a session token value
 1086+ * which can be used in edit forms to show that the user's
 1087+ * login credentials aren't being hijacked with a foreign form
 1088+ * submission.
 1089+ *
 1090+ * @return string
 1091+ * @access public
 1092+ */
 1093+ function editToken() {
 1094+ if( !isset( $_SESSION['wsEditToken'] ) ) {
 1095+ $token = dechex( mt_rand() ) . dechex( mt_rand() );
 1096+ $_SESSION['wsEditToken'] = $token;
 1097+ }
 1098+ return $_SESSION['wsEditToken'];
 1099+ }
 1100+
 1101+ /**
 1102+ * Check given value against the token value stored in the session.
 1103+ * A match should confirm that the form was submitted from the
 1104+ * user's own login session, not a form submission from a third-party
 1105+ * site.
 1106+ *
 1107+ * @param string $val
 1108+ * @return bool
 1109+ * @access public
 1110+ */
 1111+ function matchEditToken( $val ) {
 1112+ if( !isset( $_SESSION['wsEditToken'] ) )
 1113+ return false;
 1114+ return $_SESSION['wsEditToken'] == $val;
 1115+ }
10831116 }
10841117
10851118 ?>
Index: branches/REL1_4/phase3/includes/EditPage.php
@@ -94,11 +94,17 @@
9595 # If the form is incomplete, force to preview.
9696 $this->preview = true;
9797 } else {
98 - # Some browsers will not report any submit button
99 - # if the user hits enter in the comment box.
100 - # The unmarked state will be assumed to be a save,
101 - # if the form seems otherwise complete.
102 - $this->preview = $request->getCheck( 'wpPreview' );
 98+ if( $this->tokenOk( $request ) ) {
 99+ # Some browsers will not report any submit button
 100+ # if the user hits enter in the comment box.
 101+ # The unmarked state will be assumed to be a save,
 102+ # if the form seems otherwise complete.
 103+ $this->preview = $request->getCheck( 'wpPreview' );
 104+ } else {
 105+ # Page might be a hack attempt posted from
 106+ # an external site. Preview instead of saving.
 107+ $this->preview = true;
 108+ }
103109 }
104110 $this->save = !$this->preview;
105111 if( !preg_match( '/^\d{14}$/', $this->edittime )) {
@@ -125,6 +131,24 @@
126132 $this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
127133 }
128134
 135+ /**
 136+ * Make sure the form isn't faking a user's credentials.
 137+ *
 138+ * @param WebRequest $request
 139+ * @return bool
 140+ * @access private
 141+ */
 142+ function tokenOk( &$request ) {
 143+ global $wgUser;
 144+ if( $wgUser->getId() == 0 ) {
 145+ # Anonymous users may not have a session
 146+ # open. Don't tokenize.
 147+ return true;
 148+ } else {
 149+ return $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
 150+ }
 151+ }
 152+
129153 function submit() {
130154 $this->edit();
131155 }
@@ -515,6 +539,20 @@
516540 <input type='hidden' value=\"" . htmlspecialchars( $this->section ) . "\" name=\"wpSection\" />
517541 <input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n" );
518542
 543+ if ( 0 != $wgUser->getID() ) {
 544+ /**
 545+ * To make it harder for someone to slip a user a page
 546+ * which submits an edit form to the wiki without their
 547+ * knowledge, a random token is associated with the login
 548+ * session. If it's not passed back with the submission,
 549+ * we won't save the page, or render user JavaScript and
 550+ * CSS previews.
 551+ */
 552+ $token = htmlspecialchars( $wgUser->editToken() );
 553+ $wgOut->addHTML( "
 554+<input type='hidden' value=\"$token\" name=\"wpEditToken\" />\n" );
 555+ }
 556+
519557 if ( $isConflict ) {
520558 require_once( "DifferenceEngine.php" );
521559 $wgOut->addHTML( "<h2>" . wfMsg( "yourdiff" ) . "</h2>\n" );
Index: branches/REL1_4/phase3/includes/SkinTemplate.php
@@ -816,7 +816,7 @@
817817 $action = $wgRequest->getText('action');
818818
819819 # if we're previewing the CSS page, use it
820 - if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
 820+ if( $wgTitle->isCssSubpage() and $this->userCanPreview( $action ) ) {
821821 # we are previewing
822822 $siteargs = "&maxage=0";
823823 # use the raw css just posted directly in the header of the page
@@ -856,7 +856,7 @@
857857 $action = $wgRequest->getText('action');
858858
859859 if( $wgAllowUserJs && $this->loggedin ) {
860 - if($wgTitle->isJsSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
 860+ if( $wgTitle->isJsSubpage() and $this->userCanPreview( $action ) ) {
861861 # XXX: additional security check/prompt?
862862 $this->userjsprev = '/*<![CDATA[*/ ' . $wgRequest->getText('wpTextbox1') . ' /*]]>*/';
863863 } else {
Index: branches/REL1_4/phase3/includes/DefaultSettings.php
@@ -19,7 +19,7 @@
2020 * MediaWiki version number
2121 * @global string $wgVersion
2222 */
23 -$wgVersion = '1.4beta5';
 23+$wgVersion = '1.4beta6';
2424
2525 /**
2626 * Name of the site.
@@ -583,7 +583,7 @@
584584
585585 # This is the list of preferred extensions for uploading files. Uploading
586586 # files with extensions not in this list will trigger a warning.
587 -$wgFileExtensions = array( 'png', 'gif', 'jpg', 'jpeg', 'ogg' );
 587+$wgFileExtensions = array( 'png', 'gif', 'jpg', 'jpeg' );
588588
589589 # Files with these extensions will never be allowed as uploads.
590590 $wgFileBlacklist = array(
@@ -767,10 +767,14 @@
768768 $wgExtensionFunctions = array();
769769
770770 # Allow user Javascript page?
771 -$wgAllowUserJs = true;
 771+# This enables a lot of neat customizations, but may
 772+# increase security risk to users and server load.
 773+$wgAllowUserJs = false;
772774
773775 # Allow user Cascading Style Sheets (CSS)?
774 -$wgAllowUserCss = true;
 776+# This enables a lot of neat customizations, but may
 777+# increase security risk to users and server load.
 778+$wgAllowUserCss = false;
775779
776780 # Use the site's Javascript page?
777781 $wgUseSiteJs = true;
Index: branches/REL1_4/phase3/includes/Skin.php
@@ -210,6 +210,30 @@
211211 return $r;
212212 }
213213
 214+ /**
 215+ * To make it harder for someone to slip a user a fake
 216+ * user-JavaScript or user-CSS preview, a random token
 217+ * is associated with the login session. If it's not
 218+ * passed back with the preview request, we won't render
 219+ * the code.
 220+ *
 221+ * @param string $action
 222+ * @return bool
 223+ * @access private
 224+ */
 225+ function userCanPreview( $action ) {
 226+ global $wgTitle, $wgRequest, $wgUser;
 227+
 228+ if( $action != 'submit' )
 229+ return false;
 230+ if( !$wgRequest->wasPosted() )
 231+ return false;
 232+ if( !$wgTitle->userCanEditCssJsSubpage() )
 233+ return false;
 234+ return $wgUser->matchEditToken(
 235+ $wgRequest->getVal( 'wpEditToken' ) );
 236+ }
 237+
214238 # get the user/site-specific stylesheet, SkinPHPTal called from RawPage.php (settings are cached that way)
215239 function getUserStylesheet() {
216240 global $wgOut, $wgStylePath, $wgContLang, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss;
@@ -218,7 +242,7 @@
219243 $s = "@import \"$wgStylePath/$sheet\";\n";
220244 if($wgContLang->isRTL()) $s .= "@import \"$wgStylePath/common/common_rtl.css\";\n";
221245 if( $wgAllowUserCss && $wgUser->getID() != 0 ) { # logged in
222 - if($wgTitle->isCssSubpage() and $action == 'submit' and $wgTitle->userCanEditCssJsSubpage()) {
 246+ if($wgTitle->isCssSubpage() && $this->userCanPreview( $action ) ) {
223247 $s .= $wgRequest->getText('wpTextbox1');
224248 } else {
225249 $userpage = $wgContLang->getNsText( Namespace::getUser() ) . ":" . $wgUser->getName();
Index: branches/REL1_4/phase3/RELEASE-NOTES
@@ -4,17 +4,47 @@
55 setting since version 1.2.0. If you have it on, turn it *off* if you can.
66
77
8 -== MediaWiki 1.4 BETA 5 ==
 8+== MediaWiki 1.4 BETA 6 ==
99
10 -MediaWiki 1.4beta5 is a security and bug fix release for the 1.4 beta
11 -series. Previous MediaWiki 1.4 beta releases include an input validation
 10+MediaWiki 1.4beta6 is a security and bug fix release for the 1.4 beta
 11+series.
 12+
 13+An attacker could craft a URL which, when visited by a particular
 14+logged-in user, would execute arbitrary JavaScript code on the user's
 15+browser in the wiki's site context. This attack has been blocked, and as
 16+an extra precaution the user CSS and JavaScript subpage support is now
 17+disabled by default. Sites which want this ability may set $wgAllowUserCss
 18+and $wgAllowUserJs in LocalSettings.php.
 19+
 20+Additional protections have been added against off-site form submissions
 21+hijacking user credentials. Authors of bot tools may need to update their
 22+code to include additional fields.
 23+
 24+These problems affects the 1.3.x releases as well; 1.3 users should
 25+upgrade to 1.3.10.
 26+
 27+Note that 1.4 beta releases prior to beta 5 include an input validation
1228 error which could lead to execution of arbitrary PHP code on the server.
 29+Users of older betas should upgrade immediately to the current version.
1330
14 -All users of 1.4 beta releases are strongly urged to upgrade to 1.4beta5
15 -immediately. The 1.3.x stable release series is not affected by this
16 -problem.
1731
 32+Beta 6 also introduces the use of rel="nofollow" attributes on external
 33+links in wiki pages to reduce the effectiveness of wiki spam. This will
 34+cause participating search engines to ignore external URL links from wiki
 35+pages for purposes of page relevancy ranking.
1836
 37+The current implementation adds this attribute to _all_ external URL
 38+links in wiki text (but not internal [[wiki links]] or interwiki links).
 39+To disable the attribute for _all_ external links, add this line to your
 40+LocalSettings.php:
 41+
 42+ $wgNoFollowLinks = false
 43+
 44+For background information on nofollow see:
 45+
 46+ http://www.google.com/googleblog/2005/01/preventing-comment-spam.html
 47+
 48+
1949 ''''' Thinking of using MySQL 4.1? Please read this first! '''''
2050 ''''' Your PHP installation probably uses the OLD protocol '''''
2151 ''''' http://dev.mysql.com/doc/mysql/en/Old_client.html '''''
@@ -279,6 +309,13 @@
280310 * (bug 1435) Fixed many CSS errors
281311 * (bug 1457) Fix XHTML validation on category column list
282312 * (bug 1458) Don't save if edit form submission is incomplete
 313+* Logged-in edits and preview of user CSS/JS are now locked to a session token.
 314+* Per-user CSS and JavaScript subpage customizations now disabled by default.
 315+ They can be re-enabled via $wgAllowUserJs and $wgAllowUserCss.
 316+* Removed .ogg from the default uploads whitelist as an extra precaution.
 317+ If your web server is configured to serve Ogg files with the correct
 318+ Content-Type header, you can re-add it in LocalSettings.php:
 319+ $wgFileExtensions[] = 'ogg';
283320
284321 === Caveats ===
285322

Status & tagging log