SECURITY: Throttle uploads
authorcsteipp <csteipp@wikimedia.org>
Thu, 12 Mar 2015 01:44:44 +0000 (18:44 -0700)
committerChad Horohoe <chadh@wikimedia.org>
Fri, 16 Oct 2015 18:23:18 +0000 (11:23 -0700)
Add throttle check in ApiUpload and SpecialUpload.

Bug: T91850
Change-Id: If33cc99f304aab2486507c7500b4abb06b6b5d70

includes/DefaultSettings.php
includes/api/ApiUpload.php
includes/specials/SpecialUpload.php
includes/upload/UploadBase.php

index 9eff602..c491b15 100644 (file)
@@ -5214,6 +5214,12 @@ $wgRateLimits = array(
                'ip' => null, // for each anon and recent account
                'subnet' => null, // ... within a /24 subnet in IPv4 or /64 in IPv6
        ),
+       'upload' => array(
+               'user' => null,
+               'newbie' => null,
+               'ip' => null,
+               'subnet' => null,
+       ),
        'move' => array(
                'user' => null,
                'newbie' => null,
index b621cb0..83a604c 100644 (file)
@@ -139,6 +139,12 @@ class ApiUpload extends ApiBase {
                        return $this->getStashResult( $warnings );
                }
 
+               // Check throttle after we've handled warnings
+               if ( UploadBase::isThrottled( $this->getUser() )
+               ) {
+                       $this->dieUsageMsg( 'actionthrottledtext' );
+               }
+
                // This is the most common case -- a normal upload with no warnings
                // performUpload will return a formatted properly for the API with status
                return $this->performUpload( $warnings );
index 7b98a34..6692bb6 100644 (file)
@@ -475,6 +475,14 @@ class SpecialUpload extends SpecialPage {
                        }
                }
 
+               // This is as late as we can throttle, after expected issues have been handled
+               if ( UploadBase::isThrottled( $this->getUser() ) ) {
+                       $this->showRecoverableUploadError(
+                               $this->msg( 'actionthrottledtext' )->escaped()
+                       );
+                       return;
+               }
+
                // Get the page text if this is not a reupload
                if ( !$this->mForReUpload ) {
                        $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
index 5f4a16a..f600e32 100644 (file)
@@ -125,6 +125,16 @@ abstract class UploadBase {
                return true;
        }
 
+       /**
+        * Returns true if the user has surpassed the upload rate limit, false otherwise.
+        *
+        * @param User $user
+        * @return bool
+        */
+       public static function isThrottled( $user ) {
+               return $user->pingLimiter( 'upload' );
+       }
+
        // Upload handlers. Should probably just be a global.
        private static $uploadHandlers = array( 'Stash', 'File', 'Url' );