Plugin Directory


Ignore:
Timestamp:
06/05/2026 08:55:56 AM (5 months ago)
Author:
sstoqnov
Message:

Bump to 1.2.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sg-ai-studio/trunk/core/Helper/HelperAuth.php

    r3505951 r3562098  
    103103        private ?string $token = null;
    104104        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        );
    105121
    106122        public function __construct(
    … …  
    172188        }
    173189
     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
    174232        private function generate_token( array $key_data, int $retries = 5, ?array $extra_payload = null ): string
    175233        {
    … …  
    187245                }
    188246
     247                $this->validate_key_strength( $private_key, $this->algorithm, true );
    189248                $token         = JWT::encode( $payload, $private_key, $this->algorithm );
    190249                $token_request = new TokenRequest( $token, $service, $client, $client_key );
    … …  
    323382                foreach ( $algorithms as $algorithm ) {
    324383                        try {
     384                                $this->validate_key_strength( trim( $service_key['key_pub'] ), $algorithm, false );
    325385                                $decoded_data = JWT::decode( $token, new Key( trim( $service_key['key_pub'] ), $algorithm ) );
    326386                                $decoded_data = (array) $decoded_data;
    … …  
    372432                        $key_value = trim( $public_key['key_pub'] );
    373433
     434                        $this->validate_key_strength( $key_value, $this->algorithm, false );
    374435                        $decoded_data = JWT::decode( $token, new Key( $key_value, $this->algorithm ) );
    375436                        $decoded_data = (array) $decoded_data;
Note: See TracChangeset for help on using the changeset viewer.