From 101650b65d4fdd9b392cd899c765f8ce5bf3addd Mon Sep 17 00:00:00 2001 From: "Santos, Felipe Almeida dos" Date: Fri, 25 Oct 2024 15:27:44 -0300 Subject: [PATCH] chore: add EXTR_SKIP to extract() calls to remediate vulnerability: Possible Variable Overwrite: Global Scope (CWE ID 473) --- phpseclib/Common/Functions/Strings.php | 2 +- phpseclib/Crypt/Common/Formats/Keys/PKCS8.php | 10 +++++----- phpseclib/Crypt/Common/Formats/Keys/PuTTY.php | 6 +++--- phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php | 2 +- phpseclib/Crypt/DSA/PrivateKey.php | 2 +- phpseclib/Crypt/DSA/PublicKey.php | 2 +- phpseclib/Crypt/EC/PrivateKey.php | 2 +- phpseclib/Crypt/EC/PublicKey.php | 2 +- phpseclib/Crypt/RSA.php | 2 +- phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php | 4 ++-- phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php | 2 +- phpseclib/File/ASN1.php | 2 +- phpseclib/File/X509.php | 4 ++-- phpseclib/Math/BigInteger.php | 4 ++-- phpseclib/Math/BigInteger/Engines/BCMath.php | 2 +- .../Engines/BCMath/Reductions/Barrett.php | 2 +- phpseclib/Math/BigInteger/Engines/Engine.php | 6 +++--- phpseclib/Math/BigInteger/Engines/GMP.php | 2 +- .../BigInteger/Engines/PHP/Reductions/Barrett.php | 2 +- phpseclib/Net/SFTP.php | 4 ++-- phpseclib/Net/SFTP/Stream.php | 2 +- phpseclib/Net/SSH2.php | 14 +++++++------- 22 files changed, 40 insertions(+), 40 deletions(-) diff --git a/phpseclib/Common/Functions/Strings.php b/phpseclib/Common/Functions/Strings.php index 30d77418..3b09d114 100644 --- a/phpseclib/Common/Functions/Strings.php +++ b/phpseclib/Common/Functions/Strings.php @@ -119,7 +119,7 @@ abstract class Strings // 64-bit floats can be used to get larger numbers then 32-bit signed ints would allow // for. sure, you're not gonna get the full precision of 64-bit numbers but just because // you need > 32-bit precision doesn't mean you need the full 64-bit precision - extract(unpack('Nupper/Nlower', self::shift($data, 8))); + extract(unpack('Nupper/Nlower', self::shift($data, 8)), EXTR_SKIP); $temp = $upper ? 4294967296 * $upper : 0; $temp += $lower < 0 ? ($lower & 0x7FFFFFFFF) + 0x80000000 : $lower; // $temp = hexdec(bin2hex(self::shift($data, 8))); diff --git a/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php index 2bec045b..dfd93e26 100644 --- a/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php @@ -345,7 +345,7 @@ abstract class PKCS8 extends PKCS if (!$temp) { throw new RuntimeException('Unable to decode BER'); } - extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP)); + extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP), EXTR_SKIP); $iterationCount = (int) $iterationCount->toString(); $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); $key = $cipher->decrypt($decrypted['encryptedData']); @@ -363,7 +363,7 @@ abstract class PKCS8 extends PKCS throw new RuntimeException('Unable to decode BER'); } $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); - extract($temp); + extract($temp, EXTR_SKIP); $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); $meta['meta']['cipher'] = $encryptionScheme['algorithm']; @@ -373,7 +373,7 @@ abstract class PKCS8 extends PKCS throw new RuntimeException('Unable to decode BER'); } $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); - extract($temp); + extract($temp, EXTR_SKIP); if (!$cipher instanceof RC2) { $cipher->setIV($encryptionScheme['parameters']['octetString']); @@ -382,7 +382,7 @@ abstract class PKCS8 extends PKCS if (!$temp) { throw new RuntimeException('Unable to decode BER'); } - extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP)); + extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP), EXTR_SKIP); $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); switch ($effectiveKeyLength) { case 160: @@ -409,7 +409,7 @@ abstract class PKCS8 extends PKCS } $prf = ['algorithm' => 'id-hmacWithSHA1']; $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); - extract($params); + extract($params, EXTR_SKIP); $meta['meta']['prf'] = $prf['algorithm']; $hash = str_replace('-', '/', substr($prf['algorithm'], 11)); $params = [ diff --git a/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php index 83697ed5..3fa3b577 100644 --- a/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php +++ b/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php @@ -186,7 +186,7 @@ abstract class PuTTY $source = Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); - extract(unpack('Nlength', Strings::shift($public, 4))); + extract(unpack('Nlength', Strings::shift($public, 4)), EXTR_SKIP); $newtype = Strings::shift($public, $length); if ($newtype != $type) { throw new RuntimeException('The binary type does not match the human readable type field'); @@ -214,7 +214,7 @@ abstract class PuTTY $parallelism = trim(preg_replace('#Argon2-Parallelism: (\d+)#', '$1', $key[$offset++])); $salt = Strings::hex2bin(trim(preg_replace('#Argon2-Salt: ([0-9a-f]+)#', '$1', $key[$offset++]))); - extract(self::generateV3Key($password, $flavour, (int)$memory, (int)$passes, $salt)); + extract(self::generateV3Key($password, $flavour, (int)$memory, (int)$passes, $salt), EXTR_SKIP); break; case 2: @@ -306,7 +306,7 @@ abstract class PuTTY $key .= "Argon2-Passes: 13\r\n"; $key .= "Argon2-Parallelism: 1\r\n"; $key .= "Argon2-Salt: " . Strings::bin2hex($salt) . "\r\n"; - extract(self::generateV3Key($password, 'Argon2id', 8192, 13, $salt)); + extract(self::generateV3Key($password, 'Argon2id', 8192, 13, $salt), EXTR_SKIP); $hash = new Hash('sha256'); $hash->setKey($hashkey); diff --git a/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php b/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php index 50f3856d..102c0b32 100644 --- a/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php +++ b/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php @@ -59,7 +59,7 @@ abstract class PuTTY extends Progenitor if (!isset($components['private'])) { return $components; } - extract($components); + extract($components, EXTR_SKIP); unset($components['public'], $components['private']); [$p, $q, $g, $y] = Strings::unpackSSH2('iiii', $public); diff --git a/phpseclib/Crypt/DSA/PrivateKey.php b/phpseclib/Crypt/DSA/PrivateKey.php index e781963a..a6311905 100644 --- a/phpseclib/Crypt/DSA/PrivateKey.php +++ b/phpseclib/Crypt/DSA/PrivateKey.php @@ -88,7 +88,7 @@ final class PrivateKey extends DSA implements Common\PrivateKey return $signature; } - extract(ASN1Signature::load($signature)); + extract(ASN1Signature::load($signature), EXTR_SKIP); return $format::save($r, $s); } diff --git a/phpseclib/Crypt/DSA/PublicKey.php b/phpseclib/Crypt/DSA/PublicKey.php index 77dc8f4a..761d9ae9 100644 --- a/phpseclib/Crypt/DSA/PublicKey.php +++ b/phpseclib/Crypt/DSA/PublicKey.php @@ -41,7 +41,7 @@ final class PublicKey extends DSA implements Common\PublicKey if ($params === false || count($params) != 2) { return false; } - extract($params); + extract($params, EXTR_SKIP); if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; diff --git a/phpseclib/Crypt/EC/PrivateKey.php b/phpseclib/Crypt/EC/PrivateKey.php index 5ba6e4fc..a333d237 100644 --- a/phpseclib/Crypt/EC/PrivateKey.php +++ b/phpseclib/Crypt/EC/PrivateKey.php @@ -156,7 +156,7 @@ final class PrivateKey extends EC implements Common\PrivateKey return $signature; } - extract(ASN1Signature::load($signature)); + extract(ASN1Signature::load($signature), EXTR_SKIP); return $this->formatSignature($r, $s); } diff --git a/phpseclib/Crypt/EC/PublicKey.php b/phpseclib/Crypt/EC/PublicKey.php index b6e619e4..66109bd1 100644 --- a/phpseclib/Crypt/EC/PublicKey.php +++ b/phpseclib/Crypt/EC/PublicKey.php @@ -116,7 +116,7 @@ final class PublicKey extends EC implements Common\PublicKey if ($params === false || count($params) != 2) { return false; } - extract($params); + extract($params, EXTR_SKIP); if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index c202425d..6716a483 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -352,7 +352,7 @@ abstract class RSA extends AsymmetricKey if ($i != $num_primes) { $primes[$i] = BigInteger::randomPrime($regSize); } else { - extract(BigInteger::minMaxBits($bits)); + extract(BigInteger::minMaxBits($bits), EXTR_SKIP); /** @var BigInteger $min * @var BigInteger $max */ diff --git a/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php index 593a2533..f8e1a56a 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php @@ -83,7 +83,7 @@ abstract class MSBLOB // PUBLICKEYSTRUC publickeystruc // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx - extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8))); + extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8)), EXTR_SKIP); /** * @var string $type * @var string $version @@ -116,7 +116,7 @@ abstract class MSBLOB // RSAPUBKEY rsapubkey // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit - extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12))); + extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12)), EXTR_SKIP); /** * @var integer $magic * @var integer $bitlen diff --git a/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php b/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php index fbad5eef..e9e6290c 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php @@ -60,7 +60,7 @@ abstract class PuTTY extends Progenitor if (!isset($components['private'])) { return $components; } - extract($components); + extract($components, EXTR_SKIP); unset($components['public'], $components['private']); $isPublicKey = false; diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 3eb746a2..3119fc7a 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -272,7 +272,7 @@ abstract class ASN1 // tags of indefinte length don't really have a header length; this length includes the tag $current += ['headerlength' => $length + 2]; $start += $length; - extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); + extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)), EXTR_SKIP); /** @var integer $length */ } else { $current += ['headerlength' => 2]; diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index cf77cc94..91123f0c 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -618,7 +618,7 @@ class X509 $extensions = &$this->subArray($root, $path, !empty($this->extensionValues)); foreach ($this->extensionValues as $id => $data) { - extract($data); + extract($data, EXTR_SKIP); $newext = [ 'extnId' => $id, 'extnValue' => $value, @@ -1792,7 +1792,7 @@ class X509 $dn = $this->getDN(self::DN_CANON, $dn); $hash = new Hash('sha1'); $hash = $hash->hash($dn); - extract(unpack('Vhash', $hash)); + extract(unpack('Vhash', $hash), EXTR_SKIP); return strtolower(Strings::bin2hex(pack('N', $hash))); } diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index 831ddd7c..0f94973b 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -309,7 +309,7 @@ class BigInteger implements \JsonSerializable */ public function extendedGCD(BigInteger $n): array { - extract($this->value->extendedGCD($n->value)); + extract($this->value->extendedGCD($n->value), EXTR_SKIP); /** * @var BigInteger $gcd * @var BigInteger $x @@ -550,7 +550,7 @@ class BigInteger implements \JsonSerializable self::initialize_static_variables(); $class = self::$mainEngine; - extract($class::minMaxBits($bits)); + extract($class::minMaxBits($bits), EXTR_SKIP); /** @var BigInteger $min * @var BigInteger $max */ diff --git a/phpseclib/Math/BigInteger/Engines/BCMath.php b/phpseclib/Math/BigInteger/Engines/BCMath.php index 76ccc5e7..129f6774 100644 --- a/phpseclib/Math/BigInteger/Engines/BCMath.php +++ b/phpseclib/Math/BigInteger/Engines/BCMath.php @@ -274,7 +274,7 @@ class BCMath extends Engine */ public function gcd(BCMath $n): BCMath { - extract($this->extendedGCD($n)); + extract($this->extendedGCD($n), EXTR_SKIP); /** @var BCMath $gcd */ return $gcd; } diff --git a/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php b/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php index c46c2a64..cf401723 100644 --- a/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php +++ b/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php @@ -92,7 +92,7 @@ abstract class Barrett extends Base 'm1' => $m1, // m.length ]; } else { - extract($cache[self::DATA][$key]); + extract($cache[self::DATA][$key], EXTR_SKIP); } $cutoff = $m_length + ($m_length >> 1); diff --git a/phpseclib/Math/BigInteger/Engines/Engine.php b/phpseclib/Math/BigInteger/Engines/Engine.php index bc6636be..8f9c6df2 100644 --- a/phpseclib/Math/BigInteger/Engines/Engine.php +++ b/phpseclib/Math/BigInteger/Engines/Engine.php @@ -311,7 +311,7 @@ abstract class Engine implements \JsonSerializable return $this->normalize($n->subtract($temp)); } - extract($this->extendedGCD($n)); + extract($this->extendedGCD($n), EXTR_SKIP); /** * @var Engine $gcd * @var Engine $x @@ -706,7 +706,7 @@ abstract class Engine implements \JsonSerializable */ public static function random(int $size): Engine { - extract(static::minMaxBits($size)); + extract(static::minMaxBits($size), EXTR_SKIP); /** * @var BigInteger $min * @var BigInteger $max @@ -721,7 +721,7 @@ abstract class Engine implements \JsonSerializable */ public static function randomPrime(int $size): Engine { - extract(static::minMaxBits($size)); + extract(static::minMaxBits($size), EXTR_SKIP); /** * @var static $min * @var static $max diff --git a/phpseclib/Math/BigInteger/Engines/GMP.php b/phpseclib/Math/BigInteger/Engines/GMP.php index 544d20fd..6fcd5881 100644 --- a/phpseclib/Math/BigInteger/Engines/GMP.php +++ b/phpseclib/Math/BigInteger/Engines/GMP.php @@ -271,7 +271,7 @@ class GMP extends Engine */ public function extendedGCD(GMP $n): array { - extract(gmp_gcdext($this->value, $n->value)); + extract(gmp_gcdext($this->value, $n->value), EXTR_SKIP); return [ 'gcd' => $this->normalize(new self($g)), diff --git a/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php b/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php index e82f1947..b20d9ff7 100644 --- a/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php +++ b/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php @@ -97,7 +97,7 @@ abstract class Barrett extends Base 'm1' => $m1, // m.length ]; } else { - extract($cache[self::DATA][$key]); + extract($cache[self::DATA][$key], EXTR_SKIP); } $cutoff = $m_length + ($m_length >> 1); diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index b6739e13..1928ac0d 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -3023,7 +3023,7 @@ class SFTP extends SSH2 if (strlen($this->packet_buffer) < 4) { throw new RuntimeException('Packet is too small'); } - extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4))); + extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4)), EXTR_SKIP); /** @var integer $length */ $tempLength = $length; @@ -3054,7 +3054,7 @@ class SFTP extends SSH2 $this->packet_type = ord(Strings::shift($this->packet_buffer)); if ($this->use_request_id) { - extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))); // remove the request id + extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4)), EXTR_SKIP); // remove the request id $length -= 5; // account for the request id and the packet type } else { $length -= 1; // account for the packet type diff --git a/phpseclib/Net/SFTP/Stream.php b/phpseclib/Net/SFTP/Stream.php index 8bd71ac8..d9abb806 100644 --- a/phpseclib/Net/SFTP/Stream.php +++ b/phpseclib/Net/SFTP/Stream.php @@ -124,7 +124,7 @@ class Stream protected function parse_path(string $path) { $orig = $path; - extract(parse_url($path) + ['port' => 22]); + extract(parse_url($path) + ['port' => 22], EXTR_SKIP); if (isset($query)) { $path .= '?' . $query; } elseif (preg_match('/(\?|\?#)$/', $orig)) { diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index a3097463..a20bb805 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -3318,7 +3318,7 @@ class SSH2 } $padding_length = 0; $payload = $packet->plain; - extract(unpack('Cpadding_length', Strings::shift($payload, 1))); + extract(unpack('Cpadding_length', Strings::shift($payload, 1)), EXTR_SKIP); if ($padding_length > 0) { Strings::pop($payload, $padding_length); } @@ -3400,13 +3400,13 @@ class SSH2 switch ($this->decryptName) { case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': - extract(unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size))); + extract(unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size)), EXTR_SKIP); $packet->size = $packet_length_header_size + $packet_length + $this->decrypt_block_size; // expect tag break; case 'chacha20-poly1305@openssh.com': $this->lengthDecrypt->setNonce(pack('N2', 0, $this->get_seq_no)); $packet_length_header = $this->lengthDecrypt->decrypt(substr($packet->raw, 0, $packet_length_header_size)); - extract(unpack('Npacket_length', $packet_length_header)); + extract(unpack('Npacket_length', $packet_length_header), EXTR_SKIP); $packet->size = $packet_length_header_size + $packet_length + 16; // expect tag break; default: @@ -3415,17 +3415,17 @@ class SSH2 return; } $packet->plain = $this->decrypt->decrypt(substr($packet->raw, 0, $this->decrypt_block_size)); - extract(unpack('Npacket_length', Strings::shift($packet->plain, $packet_length_header_size))); + extract(unpack('Npacket_length', Strings::shift($packet->plain, $packet_length_header_size)), EXTR_SKIP); $packet->size = $packet_length_header_size + $packet_length; $added_validation_length = $packet_length_header_size; } else { - extract(unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size))); + extract(unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size)), EXTR_SKIP); $packet->size = $packet_length_header_size + $packet_length; } break; } } else { - extract(unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size))); + extract(unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size)), EXTR_SKIP); $packet->size = $packet_length_header_size + $packet_length; $added_validation_length = $packet_length_header_size; } @@ -3508,7 +3508,7 @@ class SSH2 switch (ord($payload[0])) { case MessageType::CHANNEL_REQUEST: if (strlen($payload) == 31) { - extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); + extract(unpack('cpacket_type/Nchannel/Nlength', $payload), EXTR_SKIP); if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { if (ord(substr($payload, 9 + $length))) { // want reply $this->send_binary_packet(pack('CN', MessageType::CHANNEL_SUCCESS, $this->server_channels[$channel]));