From cc59f8f97cb67ef1b8caef90910f66fc13e0b781 Mon Sep 17 00:00:00 2001 From: Rich Lott / Artful Robot Date: Thu, 14 May 2020 07:20:11 +0100 Subject: [PATCH] Allow HEAD requests to generate a form key --- CRM/Core/Controller.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CRM/Core/Controller.php b/CRM/Core/Controller.php index 9d9bba46cca3..014f15298e26 100644 --- a/CRM/Core/Controller.php +++ b/CRM/Core/Controller.php @@ -284,11 +284,23 @@ public function key($name, $addSequence = FALSE, $ignoreKey = FALSE) { return NULL; } - $key = $_REQUEST['qfKey'] ?? NULL; - if (!$key && $_SERVER['REQUEST_METHOD'] === 'GET') { + // We need a form key. Check _POST first, then _GET. + // @todo Note: we currently have to check $_REQUEST, too, since that + // is currently overwritten by civicrm_api3_contribution_page_validate. + // It's bad form to use $_REQUEST because it's ambiguous; and it's bad form + // to change superglobals anyway. If PR + // https://github.com/civicrm/civicrm-core/pull/17324 + // and/or related get merged, then we should remove the REQUEST reference here. + $key = $_POST['qfKey'] ?? $_GET['qfKey'] ?? $_REQUEST['qfKey'] ?? NULL; + if (!$key && in_array($_SERVER['REQUEST_METHOD'], ['GET', 'HEAD'])) { + // Generate a key if this is an initial request without one. + // We allow HEAD here because it is used by bots to validate URLs, so if + // we issue a 500 server error to them they may think the site is broken. $key = CRM_Core_Key::get($name, $addSequence); } else { + // Other requests that usually change data (POST, but feasibly DELETE, + // PUT, PATCH...) always require a valid key. $key = CRM_Core_Key::validate($key, $name, $addSequence); }