API debugging flag $wgDebugAPI to disable some security checks
authorYuri Astrakhan <yuriastrakhan@gmail.com>
Fri, 18 Jan 2013 15:23:17 +0000 (10:23 -0500)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 18 Jan 2013 17:58:06 +0000 (17:58 +0000)
Intentionally introduce a big security hole for debugging only.
Just like $wgShowDebug, $wgShowExceptionDetails, and $wgShowSQLErrors,
that introduce security vulnarabilities for debugging purposes,
this flag allows developers to remove some security checks in their
LocalSettings.php. This is a much safer approach than temporarily
changing production code to ignore certain conditions and later
forgetting to remove those changes before commiting the code.
Whenever enabled, a warning will allways be added to all output.

Change-Id: Ideb271dc1c9087f0843da03d024d70cc2cd776ae

RELEASE-NOTES-1.21
includes/DefaultSettings.php
includes/api/ApiBase.php
includes/api/ApiMain.php

index 0ce0593..d4ff54c 100644 (file)
@@ -180,6 +180,11 @@ production.
 * ApiQueryBase adds 'badcontinue' error code if module has 'continue' parameter.
 * (bug 35885) Removed version parameter and all getVersion() methods.
 
+=== API internal changes in 1.21 ===
+* For debugging only, a new global $wgDebugAPI removes many API restrictions when true.
+  Never use on the production servers, as this flag introduces security holes.
+  Whenever enabled, a warning will also be added to all output.
+
 === Languages updated in 1.21 ===
 
 MediaWiki supports over 350 languages. Many localisations are updated
index c13dbfd..a6d745f 100644 (file)
@@ -5992,6 +5992,22 @@ $wgEnableAPI = true;
  */
 $wgEnableWriteAPI = true;
 
+/**
+ *
+ *     WARNING: SECURITY THREAT - debug use only
+ *
+ * Disables many security checks in the API for debugging purposes.
+ * This flag should never be used on the production servers, as it introduces
+ * a number of potential security holes. Even when enabled, the validation
+ * will still be performed, but instead of failing, API will return a warning.
+ * Also, there will always be a warning notifying that this flag is set.
+ * At this point, the flag allows GET requests to go through for modules
+ * requiring POST.
+ *
+ * @since 1.21
+ */
+$wgDebugAPI = false;
+
 /**
  * API module extensions.
  * Associative array mapping module name to class name.
index 4efa7e6..78525e0 100644 (file)
@@ -1338,6 +1338,26 @@ abstract class ApiBase extends ContextSource {
                $this->dieUsage( $parsed['info'], $parsed['code'] );
        }
 
+       /**
+        * Will only set a warning instead of failing if the global $wgDebugAPI
+        * is set to true. Otherwise behaves exactly as dieUsageMsg().
+        * @param $error (array|string) Element of a getUserPermissionsErrors()-style array
+        * @since 1.21
+        */
+       public function dieUsageMsgOrDebug( $error ) {
+               global $wgDebugAPI;
+               if( $wgDebugAPI !== true ) {
+                       $this->dieUsageMsg( $error );
+               } else {
+                       if( is_string( $error ) ) {
+                               $error = array( $error );
+                       }
+                       $parsed = $this->parseMsg( $error );
+                       $this->setWarning( '$wgDebugAPI: ' . $parsed['code']
+                               . ' - ' . $parsed['info'] );
+               }
+       }
+
        /**
         * Return the error message related to a certain array
         * @param $error array Element of a getUserPermissionsErrors()-style array
index 9f88cd6..3f82d3c 100644 (file)
@@ -785,9 +785,10 @@ class ApiMain extends ApiBase {
         * @param $params Array an array with the request parameters
         */
        protected function setupExternalResponse( $module, $params ) {
-               // Ignore mustBePosted() for internal calls
-               if ( $module->mustBePosted() && !$this->getRequest()->wasPosted() ) {
-                       $this->dieUsageMsg( array( 'mustbeposted', $this->mAction ) );
+               if ( !$this->getRequest()->wasPosted() && $module->mustBePosted() ) {
+                       // Module requires POST. GET request might still be allowed
+                       // if $wgDebugApi is true, otherwise fail.
+                       $this->dieUsageMsgOrDebug( array( 'mustbeposted', $this->mAction ) );
                }
 
                // See if custom printer is used
@@ -925,6 +926,11 @@ class ApiMain extends ApiBase {
         * @param $isError bool
         */
        protected function printResult( $isError ) {
+               global $wgDebugAPI;
+               if( $wgDebugAPI !== false ) {
+                       $this->getResult()->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
+               }
+
                $this->getResult()->cleanUpUTF8();
                $printer = $this->mPrinter;
                $printer->profileIn();