CVE-2023-50708: Other (NVD-CWE-Other)
value: yii2-authclient is an extension that adds OpenID, OAuth, OAuth2 and OpenId Connect consumers for the Yii framework 2.0. In yii2-authclient prior to version 2.2.15, the Oauth1/2 `state` and OpenID Connect `nonce` is vulnerable for a `timing attack` since it is compared via regular string comparison (instead of `Yii::$app->getSecurity()->compareString()`). Version 2.2.15 contains a patch for the issue. No known workarounds are available.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
CVSS v3 base score: 9.8
Published: 2023-12-22T19:15Z
Repository: https://github.com/yiisoft/yii2-authclient
Language: PHP
Files changed: CHANGELOG.md, src/OAuth1.php, src/OAuth2.php, src/OpenIdConnect.php
Commit date: 2023-12-16 18:11:39 +0300
Commit message: Merge pull request from GHSA-w8vh-p74j-x9xp

* Fixed Oauth1/2 and OpenID Connect state/noce check

* Updated changelog for ghsa-w8vh-p74j-x9xp

---------

Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
Diff: diff --git a/CHANGELOG.md b/CHANGELOG.md
index e10f4d8..b53950c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,11 @@ Yii Framework 2 authclient extension Change Log
 2.2.15 under development
 ------------------------
 
 - Bug #364: Use issuer claim from OpenID Configuration (radwouters)
 - Enh #367: Throw more specific `ClientErrorResponseException` when the response code in `BaseOAuth::sendRequest()` is a 4xx (rhertogh)
+- Enh GHSA-w8vh-p74j-x9xp: Improved security for OAuth1, OAuth2 and OpenID Connect clients by using timing attack safe string comparsion (rhertogh)
 - Enh GHSA-rw54-6826-c8j5: Improved security for OAuth2 client by requiring an `authCodeVerifier` if PKCE is enabled and clearing it after usage (rhertogh)
 
 
 2.2.14 November 18, 2022
 ------------------------
diff --git a/src/OAuth1.php b/src/OAuth1.php
index e2fc63e..8074c6c 100644
--- a/src/OAuth1.php
+++ b/src/OAuth1.php
@@ -153,11 +153,11 @@ abstract class OAuth1 extends BaseOAuth
             if (!is_object($requestToken)) {
                 throw new InvalidParamException('Request token is required to fetch access token!');
             }
         }
 
-        if (strcmp($requestToken->getToken(), $oauthToken) !== 0) {
+        if (!Yii::$app->getSecurity()->compareString($requestToken->getToken(), $oauthToken)) {
             throw new HttpException(400, 'Invalid auth state parameter.');
         }
 
         $this->removeState('requestToken');
 
diff --git a/src/OAuth2.php b/src/OAuth2.php
index e37b4b9..137d008 100644
--- a/src/OAuth2.php
+++ b/src/OAuth2.php
@@ -116,11 +116,15 @@ abstract class OAuth2 extends BaseOAuth
     {
         if ($this->validateAuthState) {
             $authState = $this->getState('authState');
             $incomingRequest = Yii::$app->getRequest();
             $incomingState = $incomingRequest->get('state', $incomingRequest->post('state'));
-            if (!isset($incomingState) || empty($authState) || strcmp($incomingState, $authState) !== 0) {
+            if (
+                !isset($incomingState)
+                || empty($authState)
+                || !Yii::$app->getSecurity()->compareString($incomingState, $authState)
+            ) {
                 throw new HttpException(400, 'Invalid auth state parameter.');
             }
             $this->removeState('authState');
         }
 
diff --git a/src/OpenIdConnect.php b/src/OpenIdConnect.php
index ca4d1fc..126e986 100644
--- a/src/OpenIdConnect.php
+++ b/src/OpenIdConnect.php
@@ -415,11 +415,15 @@ class OpenIdConnect extends OAuth2
             $this->validateClaims($jwsData);
             $tokenConfig['params'] = array_merge($tokenConfig['params'], $jwsData);
 
             if ($this->getValidateAuthNonce()) {
                 $authNonce = $this->getState('authNonce');
-                if (!isset($jwsData['nonce']) || empty($authNonce) || strcmp($jwsData['nonce'], $authNonce) !== 0) {
+                if (
+                    !isset($jwsData['nonce'])
+                    || empty($authNonce)
+                    || !Yii::$app->getSecurity()->compareString($jwsData['nonce'], $authNonce)
+                ) {
                     throw new HttpException(400, 'Invalid auth nonce');
                 } else {
                     $this->removeState('authNonce');
                 }
             }

Vulnerable code:         if (strcmp($requestToken->getToken(), $oauthToken) !== 0) {
            if (!isset($incomingState) || empty($authState) || strcmp($incomingState, $authState) !== 0) {
                if (!isset($jwsData['nonce']) || empty($authNonce) || strcmp($jwsData['nonce'], $authNonce) !== 0) {
Fixed code: - Enh GHSA-w8vh-p74j-x9xp: Improved security for OAuth1, OAuth2 and OpenID Connect clients by using timing attack safe string comparsion (rhertogh)
        if (!Yii::$app->getSecurity()->compareString($requestToken->getToken(), $oauthToken)) {
            if (
                !isset($incomingState)
                || empty($authState)
                || !Yii::$app->getSecurity()->compareString($incomingState, $authState)
            ) {
                if (
                    !isset($jwsData['nonce'])
                    || empty($authNonce)
                    || !Yii::$app->getSecurity()->compareString($jwsData['nonce'], $authNonce)
                ) {