PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.6.8
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.6.8
3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 All 111 releases
← All changes | includes/Utils/Helper.php +38 -8 3.6.53.6.8 View file →
@@ -56,24 +56,49 @@
56 56
57 57 /**
58 58 * Collect IP from request.
59 59 *
60 + * Prefers REMOTE_ADDR since it cannot be spoofed by the client. When it is
61 + * a private/reserved address (reverse proxy, Docker bridge gateway like
62 + * 192.168.65.1, local dev), the forwarded headers are scanned for the first
63 + * public IP. If nothing public is found, the request is local: 127.0.0.1.
64 + *
60 65 * @return string
61 66 */
62 67 public static function get_ip() {
63 - $ip = '127.0.0.1'; // Local IP
64 - if (! empty($_SERVER['HTTP_CLIENT_IP'])) {
65 - $ip = $_SERVER['HTTP_CLIENT_IP'];
66 - } elseif (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
67 - $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
68 - } else {
69 - $ip = ! empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $ip;
68 + $remote_addr = ! empty($_SERVER['REMOTE_ADDR']) ? sanitize_text_field($_SERVER['REMOTE_ADDR']) : '';
69 +
70 + if (self::is_public_ip($remote_addr)) {
71 + return $remote_addr;
70 72 }
71 73
72 - return sanitize_text_field($ip);
74 + foreach (['HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP'] as $header) {
75 + if (empty($_SERVER[$header])) {
76 + continue;
77 + }
78 + $candidates = explode(',', sanitize_text_field($_SERVER[$header]));
79 + foreach ($candidates as $candidate) {
80 + $candidate = trim($candidate);
81 + if (self::is_public_ip($candidate)) {
82 + return $candidate;
83 + }
84 + }
85 + }
86 +
87 + return '127.0.0.1';
73 88 }
74 89
75 90 /**
91 + * Check whether a string is a valid public (non-private, non-reserved) IP.
92 + *
93 + * @param string $ip
94 + * @return bool
95 + */
96 + private static function is_public_ip($ip): bool {
97 + return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
98 + }
99 +
100 + /**
76 101 * Get views for front-end display
77 102 *
78 103 * @param string $name it will be file name only from the view's folder.
79 104 * @param array $data
@@ -126,8 +151,13 @@
126 151 'Authorization' => 'Bearer ' . $api_key,
127 152 'x-templately-ip' => self::get_ip(),
128 153 'x-templately-url' => home_url('/'),
129 154 'x-templately-version' => defined( 'TEMPLATELY_VERSION' ) ? constant( 'TEMPLATELY_VERSION' ) : '1.0.0',
155 + // Force JSON responses so the cloud returns JSON errors instead of an HTML
156 + // error page (which json_decode() cannot parse). Binary/XML downloads
157 + // (zip pack, attachment WXR) use their own wp_remote_* calls and bypass
158 + // this helper, so they are unaffected. Callers can override via $extra_headers.
159 + 'Accept' => 'application/json',
130 160 ];
131 161
132 162 // Add Content-Type for POST requests
133 163 if (strtoupper($method) === 'POST') {