Skip to content

Commit

Permalink
CRM_Utils_REST - Allow certain authentication styles to bypass the XM…
Browse files Browse the repository at this point in the history
…LHttpRequest requirement

Docblocks indicate the theory behind which styles are allowed and which are prohibited.
  • Loading branch information
totten committed Dec 11, 2021
1 parent 69af731 commit 0a38d14
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions CRM/Utils/REST.php
Original file line number Diff line number Diff line change
Expand Up @@ -630,12 +630,32 @@ public function loadCMSBootstrap() {
/**
* Does this request appear to be a web-service request?
*
* This is used to mitigate CSRF risks.
*
* @return bool
* TRUE if the current request appears to be web-service request (ie AJAX).
* FALSE if the current request appears to be a standalone browser page-view.
* TRUE if the current request appears to either XMLHttpRequest or non-browser-based.
* Indicated by either (a) custom headers like `X-Request-With`/`X-Civi-Auth`
* or (b) strong-secret-params that could theoretically appear in URL bar but which
* cannot be meaningfully forged for CSRF purposes (like `?api_key=SECRET` or `?_authx=SECRET`).
* FALSE if the current request looks like a standard browser request. This request may be generated by
* <A HREF>, <IFRAME>, <IMG>, `Location:`, or similar CSRF vector.
*/
protected static function isWebServiceRequest(): bool {
return array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
if (($_SERVER['HTTP_X_REQUESTED_WITH'] ?? NULL) === 'XMLHttpRequest') {
return TRUE;
}

$authx = \CRM_Core_Session::singleton()->get('authx');
$allowFlows = ['legacyrest', 'param', 'xheader'];
// <legacyrest> Current request has valid `?api_key=SECRET&key=SECRET` ==> Strong-secret params
// <param> Current request has valid `?_authx=SECRET` ==> Strong-secret param
// <xheader> Current request has valid `X-Civi-Auth:` ==> Custom header AND strong-secret param
// NOTE: Prohibited flows: `login`, `auto`, and `header` are driven by standard headers (`Cookie:`/`Authorization:`)
if (in_array($authx['flow'], $allowFlows)) {
return TRUE;
}

return FALSE;
}

}

0 comments on commit 0a38d14

Please sign in to comment.