Changeset 3562098 for sg-ai-studio/trunk/core/Helper/HelperAuth.php
- Timestamp:
- 06/05/2026 08:55:56 AM (5 months ago)
- File:
-
- 1 edited
-
sg-ai-studio/trunk/core/Helper/HelperAuth.php (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sg-ai-studio/trunk/core/Helper/HelperAuth.php
r3505951 r3562098 103 103 private ?string $token = null; 104 104 private ?float $token_expiry = null; 105 106 /** 107 * Minimum RSA modulus size (bits) accepted for RSA-based keys (RS and PS families). 108 */ 109 private const MIN_RSA_BITS = 2048; 110 111 /** 112 * Minimum secret length (bytes) per HMAC algorithm, matching the hash output size. 113 * Mirrors the key-length validation added upstream in firebase/php-jwt v7 (CVE-2025-45769), 114 * backported here so we stay on the PHP 7.4-compatible 6.x line. 115 */ 116 private const HMAC_MIN_KEY_BYTES = array( 117 'HS256' => 32, 118 'HS384' => 48, 119 'HS512' => 64, 120 ); 105 121 106 122 public function __construct( … … 172 188 } 173 189 190 /** 191 * Reject signing/verification keys that are too weak for the given algorithm. 192 * 193 * @param string $key The key material (HMAC secret, or PEM private/public key). 194 * @param string $algorithm The JWT algorithm the key will be used with. 195 * @param bool $is_private Whether $key is a private key (true) or public key (false). 196 * 197 * @throws SignApiAuthException When the key does not meet the minimum strength. 198 */ 199 private function validate_key_strength( string $key, string $algorithm, bool $is_private ): void { 200 // HMAC: the symmetric secret must be at least as long as the hash output. 201 if ( isset( self::HMAC_MIN_KEY_BYTES[ $algorithm ] ) ) { 202 $min = self::HMAC_MIN_KEY_BYTES[ $algorithm ]; 203 if ( strlen( $key ) < $min ) { 204 throw new SignApiAuthException( 205 sprintf( 'Insecure HMAC key for %s: %d bytes provided, %d required', $algorithm, strlen( $key ), $min ) 206 ); 207 } 208 return; 209 } 210 211 // Asymmetric (RS, PS, ES families): inspect the key material via OpenSSL. 212 $pkey = $is_private ? openssl_pkey_get_private( $key ) : openssl_pkey_get_public( $key ); 213 if ( false === $pkey ) { 214 throw new SignApiAuthException( 'Invalid key supplied for ' . esc_html( $algorithm ) ); 215 } 216 217 $details = openssl_pkey_get_details( $pkey ); 218 if ( false === $details ) { 219 throw new SignApiAuthException( 'Unable to read key details for ' . esc_html( $algorithm ) ); 220 } 221 222 if ( 223 ( $details['type'] ?? null ) === OPENSSL_KEYTYPE_RSA 224 && ( $details['bits'] ?? 0 ) < self::MIN_RSA_BITS 225 ) { 226 throw new SignApiAuthException( 227 sprintf( 'Insecure RSA key for %s: %d bits, minimum %d required', $algorithm, $details['bits'] ?? 0, self::MIN_RSA_BITS ) 228 ); 229 } 230 } 231 174 232 private function generate_token( array $key_data, int $retries = 5, ?array $extra_payload = null ): string 175 233 { … … 187 245 } 188 246 247 $this->validate_key_strength( $private_key, $this->algorithm, true ); 189 248 $token = JWT::encode( $payload, $private_key, $this->algorithm ); 190 249 $token_request = new TokenRequest( $token, $service, $client, $client_key ); … … 323 382 foreach ( $algorithms as $algorithm ) { 324 383 try { 384 $this->validate_key_strength( trim( $service_key['key_pub'] ), $algorithm, false ); 325 385 $decoded_data = JWT::decode( $token, new Key( trim( $service_key['key_pub'] ), $algorithm ) ); 326 386 $decoded_data = (array) $decoded_data; … … 372 432 $key_value = trim( $public_key['key_pub'] ); 373 433 434 $this->validate_key_strength( $key_value, $this->algorithm, false ); 374 435 $decoded_data = JWT::decode( $token, new Key( $key_value, $this->algorithm ) ); 375 436 $decoded_data = (array) $decoded_data;
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)