Changeset 3432152
- Timestamp:
- 01/04/2026 03:37:55 PM (3 months ago)
- Location:
- mycryptocheckout/trunk
- Files:
-
- 3 edited
-
MyCryptoCheckout.php (modified) (2 diffs)
-
readme.txt (modified) (2 diffs)
-
vendor/mycryptocheckout/api/src/v2/API.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
mycryptocheckout/trunk/MyCryptoCheckout.php
r3431562 r3432152 8 8 Plugin URI: https://mycryptocheckout.com 9 9 Text Domain: mycryptocheckout 10 Version: 2.15 710 Version: 2.158 11 11 WC tested up to: 10.4.3 12 12 License: GPLv3 … … 80 80 namespace 81 81 { 82 define( 'MYCRYPTOCHECKOUT_PLUGIN_VERSION', 2.15 7);82 define( 'MYCRYPTOCHECKOUT_PLUGIN_VERSION', 2.158 ); 83 83 /** 84 84 @brief Return the instance of MCC. -
mycryptocheckout/trunk/readme.txt
r3431562 r3432152 5 5 Requires at least: 6.2 6 6 Requires PHP: 8.0 7 Stable tag: 2.15 77 Stable tag: 2.158 8 8 Tags: bitcoin, ethereum, payments, woocommerce, bitcoin woocommerce 9 9 Tested up to: 6.9 … … 257 257 == Changelog == 258 258 259 = 2.158 = 260 261 * Fix: Fixed cloudflare ipv6 detection code. 262 * Fix: Added support for hosts that pretend they are behind cloudflare, but aren't. 263 259 264 = 2.157 = 260 265 -
mycryptocheckout/trunk/vendor/mycryptocheckout/api/src/v2/API.php
r3431562 r3432152 26 26 **/ 27 27 public static $api_url = 'https://api.mycryptocheckout.com/v2/'; 28 29 30 28 31 29 /** … … 111 109 public abstract function get_client_url(); 112 110 113 /** 114 * Check if an IP address is a valid Cloudflare proxy IP. 115 * 116 * @param string $ip The IP address to check (IPv4 or IPv6). 117 * @return bool True if the IP is in Cloudflare's ranges, false otherwise. 118 */ 119 function is_cloudflare_ip(string $ip): bool 120 { 121 // Validate IP format first 122 if (filter_var($ip, FILTER_VALIDATE_IP) === false) { 123 return false; 124 } 125 126 // Cloudflare IPv4 ranges (as of January 2026 - update periodically from https://www.cloudflare.com/ips/) 111 function is_cloudflare_ip( string $ip ): bool 112 { 113 // Cloudflare Ranges (Recommend fetching these via transient cache instead) 127 114 $ipv4_ranges = [ 128 '173.245.48.0/20', 129 '103.21.244.0/22', 130 '103.22.200.0/22', 131 '103.31.4.0/22', 132 '141.101.64.0/18', 133 '108.162.192.0/18', 134 '190.93.240.0/20', 135 '188.114.96.0/20', 136 '197.234.240.0/22', 137 '198.41.128.0/17', 138 '162.158.0.0/15', 139 '104.16.0.0/13', 140 '104.24.0.0/14', 141 '172.64.0.0/13', 142 '131.0.72.0/22' 115 '173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22', '103.31.4.0/22', 116 '141.101.64.0/18', '108.162.192.0/18', '190.93.240.0/20', '188.114.96.0/20', 117 '197.234.240.0/22', '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/13', 118 '104.24.0.0/14', '172.64.0.0/13', '131.0.72.0/22' 143 119 ]; 144 120 145 // Cloudflare IPv6 ranges146 121 $ipv6_ranges = [ 147 '2400:cb00::/32', 148 '2606:4700::/32', 149 '2803:f800::/32', 150 '2405:b500::/32', 151 '2405:8100::/32', 152 '2a06:98c0::/29', 153 '2c0f:f248::/32' 122 '2400:cb00::/32', '2606:4700::/32', '2803:f800::/32', '2405:b500::/32', 123 '2405:8100::/32', '2a06:98c0::/29', '2c0f:f248::/32' 154 124 ]; 155 125 156 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { 157 $long_ip = sprintf("%u", ip2long($ip)); 158 foreach ($ipv4_ranges as $cidr) { 159 list($subnet, $bits) = explode('/', $cidr); 160 $subnet_long = sprintf("%u", ip2long($subnet)); 161 $mask = ~((1 << (32 - $bits)) - 1); 162 if (($long_ip & $mask) === $subnet_long) { 126 // Check IPv4 127 if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) { 128 $ip_long = ip2long( $ip ); 129 foreach ( $ipv4_ranges as $range ) { 130 list( $subnet, $bits ) = explode( '/', $range ); 131 $subnet_long = ip2long( $subnet ); 132 $mask = -1 << ( 32 - $bits ); 133 $subnet_long &= $mask; 134 if ( ( $ip_long & $mask ) == $subnet_long ) { 163 135 return true; 164 136 } 165 137 } 166 138 } 167 elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { 168 // Convert IPv6 to 128-bit integer representation (using GMP for accuracy) 169 $unpacked = inet_pton($ip); 170 if ($unpacked === false) { 171 return false; 172 } 173 $hex = bin2hex($unpacked); 174 $ip_int = gmp_init($hex, 16); 175 176 foreach ($ipv6_ranges as $cidr) { 177 list($subnet, $bits) = explode('/', $cidr); 178 $unpacked_subnet = inet_pton($subnet); 179 $hex_subnet = bin2hex($unpacked_subnet); 180 $subnet_int = gmp_init($hex_subnet, 16); 181 182 $mask_int = gmp_init('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16); // Full 128-bit mask 183 if ($bits < 128) { 184 $shift = 128 - $bits; 185 $mask_int = gmp_shiftl($mask_int, -$shift); // Equivalent to left shift negative 139 // Check IPv6 (No GMP required) 140 elseif ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { 141 $ip_binary = inet_pton( $ip ); 142 foreach ( $ipv6_ranges as $range ) { 143 list( $subnet, $bits ) = explode( '/', $range ); 144 $subnet_binary = inet_pton( $subnet ); 145 146 // Create the mask 147 // IPv6 is 16 bytes (128 bits) 148 $mask = str_repeat( "\x00", 16 ); 149 for( $i = 0; $i < 16; $i++ ) { 150 if( $bits >= 8 ) { 151 $mask[$i] = "\xff"; 152 $bits -= 8; 153 } else { 154 $mask[$i] = chr( 0xff << ( 8 - $bits ) ); 155 $bits = 0; 156 } 186 157 } 187 158 188 $masked_ip = gmp_and($ip_int, $mask_int);189 if ( gmp_cmp($masked_ip, $subnet_int) === 0) {159 // Binary string comparison 160 if ( ( $ip_binary & $mask ) === ( $subnet_binary & $mask ) ) { 190 161 return true; 191 162 } … … 194 165 195 166 return false; 196 }167 } 197 168 198 169 /** … … 309 280 $remote_ip = $_SERVER['REMOTE_ADDR']; 310 281 311 // Cloudflare adds aheader with the visitor's real IP, which is what we need to check.282 // Some hosts add a Cloudflare header with the visitor's real IP, which is what we need to check. 312 283 if ( isset( $_SERVER[ 'HTTP_CF_CONNECTING_IP' ] ) ) 313 284 { 314 if ( $this->is_cloudflare_ip( $remote_ip ) ) 315 $remote_ip = $_SERVER[ 'HTTP_CF_CONNECTING_IP' ]; 316 else 317 throw new Exception( sprintf( 'Spoofed IP address %s generated from %s', $_SERVER[ 'HTTP_CF_CONNECTING_IP' ] , $remote_ip ) ); 285 // We are only interested in the HTTP_CF_CONNECTING_IP if it is NOT the same as the remote IP. 286 if ( $_SERVER[ 'HTTP_CF_CONNECTING_IP' ] !== $remote_ip ) 287 { 288 if ( $this->is_cloudflare_ip( $remote_ip ) ) 289 $remote_ip = $_SERVER[ 'HTTP_CF_CONNECTING_IP' ]; 290 else 291 { 292 throw new Exception( sprintf( 'Spoofed IP address %s generated from %s', $_SERVER[ 'HTTP_CF_CONNECTING_IP' ] , $remote_ip ) ); 293 } 294 } 318 295 } 319 296
Note: See TracChangeset
for help on using the changeset viewer.