From: Aaron Schulz Date: Fri, 18 Sep 2015 05:37:16 +0000 (-0700) Subject: Reduced the DOS potential of 404 page floods X-Git-Tag: 1.31.0-rc.0~9928^2 X-Git-Url: http://git.cyclocoop.org/%24self?a=commitdiff_plain;h=549628abe5ebb6d994d47e87baac5ec04b108e3c;p=lhc%2Fweb%2Fwiklou.git Reduced the DOS potential of 404 page floods * showMissingArticle() will now only show the log excerpt if the page was deleted very recently or if the viewing user is logged in. Crawlers and poorly written bots tend to be logged out, and logged in users are better tracked. If many hits to the same recently deleted page are made, then the innoDB buffer pool should actually have the relevant index pages in cache (especially with query grouping). * There have been several outages or DB performance problems caused by crawlers or sloppy mirrors hitting many bogus pages (due to bad URL generation, ect...). Previously a redis bloom filter was used to handle this, but was removed due to high complexity (especially if it was to be supported in multi-DC setup). This is a simpler solution to keep 404 pages cheap, as they cannot really be cached (there are innumerable possible titles that never existed). Change-Id: If948602a32deb16dba21d232d0c6128568a980d6 --- diff --git a/includes/page/Article.php b/includes/page/Article.php index 120aa5cc2b..df94ecf583 100644 --- a/includes/page/Article.php +++ b/includes/page/Article.php @@ -1234,18 +1234,33 @@ class Article implements Page { Hooks::run( 'ShowMissingArticle', array( $this ) ); - // Give extensions a chance to hide their (unrelated) log entries - $logTypes = array( 'delete', 'move' ); - $conds = array( "log_action != 'revision'" ); - Hooks::run( 'Article::MissingArticleConditions', array( &$conds, $logTypes ) ); - - # Show delete and move logs - LogEventsList::showLogExtract( $outputPage, $logTypes, $title, '', - array( 'lim' => 10, - 'conds' => $conds, - 'showIfEmpty' => false, - 'msgKey' => array( 'moveddeleted-notice' ) ) - ); + # Show delete and move logs if there were any such events. + # The logging query can DOS the site when bots/crawlers cause 404 floods, + # so be careful showing this. 404 pages must be cheap as they are hard to cache. + $cache = ObjectCache::getMainStashInstance(); + $key = wfMemcKey( 'page-recent-delete', md5( $title->getPrefixedText() ) ); + $loggedIn = $this->getContext()->getUser()->isLoggedIn(); + if ( $loggedIn || $cache->get( $key ) ) { + $logTypes = array( 'delete', 'move' ); + $conds = array( "log_action != 'revision'" ); + // Give extensions a chance to hide their (unrelated) log entries + Hooks::run( 'Article::MissingArticleConditions', array( &$conds, $logTypes ) ); + LogEventsList::showLogExtract( + $outputPage, + $logTypes, + $title, + '', + array( + 'lim' => 10, + 'conds' => $conds, + 'showIfEmpty' => false, + 'msgKey' => array( $loggedIn + ? 'moveddeleted-notice' + : 'moveddeleted-notice-recent' + ) + ) + ); + } if ( !$this->mPage->hasViewableContent() && $wgSend404Code && !$validUserPage ) { // If there's no backing content, send a 404 Not Found diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index 69b675b462..7557b043d1 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -2872,6 +2872,10 @@ class WikiPage implements Page, IDBAccessObject { $dbw->commit( __METHOD__ ); } + // Show log excerpt on 404 pages rather than just a link + $key = wfMemcKey( 'page-recent-delete', md5( $logTitle->getPrefixedText() ) ); + ObjectCache::getMainStashInstance()->set( $key, 1, 86400 ); + $this->doDeleteUpdates( $id, $content ); Hooks::run( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id, $content, $logEntry ) ); diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 3bf72d5c0b..e19452ba1b 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -691,6 +691,7 @@ "permissionserrorstext-withaction": "You do not have permission to $2, for the following {{PLURAL:$1|reason|reasons}}:", "recreate-moveddeleted-warn": "Warning: You are recreating a page that was previously deleted.\n\nYou should consider whether it is appropriate to continue editing this page.\nThe deletion and move log for this page are provided here for convenience:", "moveddeleted-notice": "This page has been deleted.\nThe deletion and move log for the page are provided below for reference.", + "moveddeleted-notice-recent": "Sorry, this page was recently deleted (within the last 24 hours).\nThe deletion and move log for the page are provided below for reference.", "log-fulllog": "View full log", "edit-hook-aborted": "Edit aborted by hook.\nIt gave no explanation.", "edit-gone-missing": "Could not update the page.\nIt appears to have been deleted.", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index d3b5a99ddb..a12dbaa5b0 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -864,6 +864,7 @@ "permissionserrorstext-withaction": "This message is \"with action\" version of {{msg-mw|Permissionserrorstext}}.\n\nParameters:\n* $1 - the number of reasons that were found why the action cannot be performed\n* $2 - one of the action-* messages (for example {{msg-mw|action-edit}}) or other such messages tagged with {{tl|doc-action}} in their documentation\n\nPlease report at [[Support]] if you are unable to properly translate this message. Also see [[phab:T16246]] (now closed) for background.", "recreate-moveddeleted-warn": "Warning shown when creating a page which has already been deleted. See for example [[Test]].", "moveddeleted-notice": "Shown on top of a deleted page in normal view modus ([{{canonicalurl:Test}} example]).", + "moveddeleted-notice-recent": "Shown on top of a recently deleted page in normal view modus ([{{canonicalurl:Test}} example]).", "log-fulllog": "Used as link text.", "edit-hook-aborted": "Used as error message.\n\nSee also:\n* {{msg-mw|edit-gone-missing}}\n* {{msg-mw|edit-conflict}}\n* {{msg-mw|edit-no-change}}\n* {{msg-mw|edit-already-exists}}", "edit-gone-missing": "Used as error message.\n\nSee also:\n* {{msg-mw|edit-hook-aborted}}\n* {{msg-mw|edit-conflict}}\n* {{msg-mw|edit-no-change}}\n* {{msg-mw|edit-already-exists}}",