security/core#71 Prevent CSRF by ensuring that AJAX endpoint of the API Explorer...
authorSeamus Lee <seamuslee001@gmail.com>
Thu, 28 Nov 2019 21:33:44 +0000 (08:33 +1100)
committerSeamus Lee <seamuslee001@gmail.com>
Wed, 4 Dec 2019 19:59:08 +0000 (06:59 +1100)
CRM/Api4/Page/AJAX.php

index 169340722eceb8748921b0e79cbf6e98545466b2..5ec8c567733cdfb7d1ac5b3a95db879a15842738 100644 (file)
@@ -23,6 +23,27 @@ class CRM_Api4_Page_AJAX extends CRM_Core_Page {
    * Handler for api4 ajax requests
    */
   public function run() {
+    $config = CRM_Core_Config::singleton();
+    if (!$config->debug && (!array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) ||
+        $_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest"
+      )
+    ) {
+      $response = [
+        'error_code' => 401,
+        'error_message' => "SECURITY ALERT: Ajax requests can only be issued by javascript clients, eg. CRM.api4().",
+      ];
+      Civi::log()->debug( "SECURITY ALERT: Ajax requests can only be issued by javascript clients, eg. CRM.api4().",
+        [
+          'IP' => $_SERVER['REMOTE_ADDR'],
+          'level' => 'security',
+          'referer' => $_SERVER['HTTP_REFERER'],
+          'reason' => 'CSRF suspected',
+        ]
+      );
+      CRM_Utils_System::setHttpHeader('Content-Type', 'application/json');
+      echo json_encode($response);
+      CRM_Utils_System::civiExit();
+    }
     try {
       // Call multiple
       if (empty($this->urlPath[3])) {