SECURITY: Fix cache mode for (un)patrolled recent changes query
authorLucas Werkmeister <mail@lucaswerkmeister.de>
Mon, 17 Dec 2018 13:02:39 +0000 (14:02 +0100)
committerReedy <reedy@wikimedia.org>
Thu, 6 Jun 2019 16:54:29 +0000 (16:54 +0000)
Restricting the list of recent changes to patrolled, not patrolled,
autopatrolled, not autopatrolled, or unpatrolled recent changes requires
special permissions (as does displaying that status in the properties of
returned entries), but we only set the cache mode to private in the
first two cases.

Bug: T212118
Change-Id: I4c3fe6e47f80ebf97fa37875c704328d08772d26

includes/api/ApiQueryRecentChanges.php

index 4b1bf2e..8ae1b66 100644 (file)
@@ -214,12 +214,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        }
 
                        // Check permissions
-                       if ( isset( $show['patrolled'] )
-                               || isset( $show['!patrolled'] )
-                               || isset( $show['unpatrolled'] )
-                               || isset( $show['autopatrolled'] )
-                               || isset( $show['!autopatrolled'] )
-                       ) {
+                       if ( $this->includesPatrollingFlags( $show ) ) {
                                if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
                                        $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
                                }
@@ -641,13 +636,23 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                return $vals;
        }
 
+       /**
+        * @param array $flagsArray flipped array (string flags are keys)
+        * @return bool
+        */
+       private function includesPatrollingFlags( array $flagsArray ) {
+               return isset( $flagsArray['patrolled'] ) ||
+                       isset( $flagsArray['!patrolled'] ) ||
+                       isset( $flagsArray['unpatrolled'] ) ||
+                       isset( $flagsArray['autopatrolled'] ) ||
+                       isset( $flagsArray['!autopatrolled'] );
+       }
+
        public function getCacheMode( $params ) {
-               if ( isset( $params['show'] ) ) {
-                       foreach ( $params['show'] as $show ) {
-                               if ( $show === 'patrolled' || $show === '!patrolled' ) {
-                                       return 'private';
-                               }
-                       }
+               if ( isset( $params['show'] ) &&
+                       $this->includesPatrollingFlags( array_flip( $params['show'] ) )
+               ) {
+                       return 'private';
                }
                if ( isset( $params['token'] ) ) {
                        return 'private';