Flood control for search function
authorMarcel Werk <burntime@woltlab.com>
Wed, 15 Dec 2021 13:17:45 +0000 (14:17 +0100)
committerMarcel Werk <burntime@woltlab.com>
Wed, 15 Dec 2021 13:17:45 +0000 (14:17 +0100)
com.woltlab.wcf/objectType.xml
wcfsetup/install/files/lib/data/search/SearchAction.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 88ae62d29ef4afd70802eba8522062c0c3df0831..de77edbb90e994f6c3574d6257bc7cd31e1bd965 100644 (file)
                        <name>com.woltlab.wcf.lostPasswordForm</name>
                        <definitionname>com.woltlab.wcf.floodControl</definitionname>
                </type>
+               <type>
+                       <name>com.woltlab.wcf.search</name>
+                       <definitionname>com.woltlab.wcf.floodControl</definitionname>
+               </type>
                <!-- deprecated -->
                <type>
                        <name>com.woltlab.wcf.page.controller</name>
index 0e70d926d91e4686d0d9b259b9a957623437a769..be7a34374e14ebda408155f5e1c675186c70e817 100644 (file)
@@ -4,7 +4,9 @@ namespace wcf\data\search;
 
 use wcf\data\AbstractDatabaseObjectAction;
 use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\NamedUserException;
 use wcf\system\exception\UserInputException;
+use wcf\system\flood\FloodControl;
 use wcf\system\search\SearchEngine;
 use wcf\system\search\SearchHandler;
 use wcf\system\search\SearchResultHandler;
@@ -34,6 +36,16 @@ class SearchAction extends AbstractDatabaseObjectAction
      */
     protected $allowGuestAccess = ['search'];
 
+    /**
+     * @var int
+     */
+    private const ALLOWED_REQUESTS_PER_24H = 600;
+
+    /**
+     * @var int
+     */
+    private const ALLOWED_REQUESTS_PER_60S = 20;
+
     /**
      * @since 5.5
      */
@@ -66,6 +78,21 @@ class SearchAction extends AbstractDatabaseObjectAction
         if (\in_array($this->parameters['sortOrder'], ['ASC', 'DESC'])) {
             $this->parameters['sortOrder'] = SEARCH_DEFAULT_SORT_ORDER;
         }
+
+        $requestsPer24h = FloodControl::getInstance()->countContent(
+            'com.woltlab.wcf.search',
+            new \DateInterval('PT24H')
+        );
+        $requestsPer60s = FloodControl::getInstance()->countContent(
+            'com.woltlab.wcf.search',
+            new \DateInterval('PT60S')
+        );
+        if (
+            $requestsPer24h['count'] >= self::ALLOWED_REQUESTS_PER_24H
+            || $requestsPer60s['count'] >= self::ALLOWED_REQUESTS_PER_60S
+        ) {
+            throw new NamedUserException(WCF::getLanguage()->getDynamicVariable('wcf.page.error.flood'));
+        }
     }
 
     /**
@@ -75,6 +102,7 @@ class SearchAction extends AbstractDatabaseObjectAction
     {
         $handler = new SearchHandler($this->parameters);
         $search = $handler->search();
+        FloodControl::getInstance()->registerContent('com.woltlab.wcf.search');
         if ($search === null) {
             return [
                 'count' => 0,
index ae817383c9ebe1cba37a0872f2bbbde65ab1934e..6cf0de0048fae72bc5259623074c93543ae5296c 100644 (file)
@@ -4392,6 +4392,7 @@ Dateianhänge:
                <item name="wcf.page.error.backward"><![CDATA[Zurück zur vorherigen Seite]]></item>
                <item name="wcf.page.error.insufficientPermissions"><![CDATA[Unzureichende Berechtigungen]]></item>
                <item name="wcf.page.error.loginAvailable"><![CDATA[Diese Seite bzw. dieser Bereich steht möglicherweise nur angemeldeten Benutzern zur Verfügung.]]></item>
+               <item name="wcf.page.error.flood"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} zu viele Aktionen dieser Art ausgeführt. Die Funktion wurde daher aus Sicherheitsgründen temporär deaktiviert. Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}versuche{else}versuchen Sie{/if} es später erneut.]]></item>
                <item name="wcf.page.jumpTo"><![CDATA[Gehe zu Seite]]></item>
                <item name="wcf.page.jumpTo.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Gib{else}Geben Sie{/if} einen Wert zwischen „1“ und „#pages#“ ein.]]></item>
                <item name="wcf.page.redirect.title"><![CDATA[Weiterleitung]]></item>
index 9aae9f865e001168d2ef230fb9362343e1a04720..c8f827b8e3714e31e1edaf4d8f1d033b450f8a9e 100644 (file)
@@ -4340,6 +4340,7 @@ Attachments:
                <item name="wcf.page.error.backward"><![CDATA[Back to previous page.]]></item>
                <item name="wcf.page.error.insufficientPermissions"><![CDATA[Insufficient Permissions]]></item>
                <item name="wcf.page.error.loginAvailable"><![CDATA[This page or section may be accessible for authorized users only.]]></item>
+               <item name="wcf.page.error.flood"><![CDATA[You have performed too many actions of this type. The function has therefore been temporarily deactivated for security reasons. Please try again later.]]></item>
                <item name="wcf.page.jumpTo"><![CDATA[Go to Page]]></item>
                <item name="wcf.page.jumpTo.description"><![CDATA[Enter a value between “1” and “#pages#”.]]></item>
                <item name="wcf.page.redirect.title"><![CDATA[Redirection]]></item>