Skip to content

Commit 90ef73e

Browse files
Nikschavanmatticbot
authored andcommitted
Status: validate the visitor IP address (#51349)
Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/32831984328 Upstream-Ref: Automattic/jetpack@908aced
1 parent cafc92b commit 90ef73e

5 files changed

Lines changed: 77 additions & 31 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"automattic/jetpack-transport-helper": "^0.3.6",
1919
"automattic/jetpack-plans": "^0.12.0",
2020
"automattic/jetpack-waf": "^0.28.11",
21-
"automattic/jetpack-status": "^6.4.0",
21+
"automattic/jetpack-status": "^6.5.0-alpha",
2222
"automattic/jetpack-protect-status": "^0.7.14",
2323
"automattic/jetpack-account-protection": "^0.3.7"
2424
},

jetpack_vendor/automattic/jetpack-status/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [6.5.0-alpha] - unreleased
9+
10+
This is an alpha version! The changes listed here are not final.
11+
12+
### Changed
13+
- Visitor: Resolve the visitor address through the site's trusted header alone where one is configured, instead of also reading the forwarded headers.
14+
- Visitor: Return only a valid IP address, and take the client address from a comma-separated forwarded header.
15+
816
## [6.4.0] - 2026-08-19
917
### Added
1018
- Visitor: Add is_tracking_automattician() to identify Automattician traffic for analytics reporting. [#51280]
@@ -575,6 +583,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
575583

576584
- Packages: Introduce a status package
577585

586+
[6.5.0-alpha]: https://github.com/Automattic/jetpack-status/compare/v6.4.0...v6.5.0-alpha
578587
[6.4.0]: https://github.com/Automattic/jetpack-status/compare/v6.3.1...v6.4.0
579588
[6.3.1]: https://github.com/Automattic/jetpack-status/compare/v6.3.0...v6.3.1
580589
[6.3.0]: https://github.com/Automattic/jetpack-status/compare/v6.2.1...v6.3.0

jetpack_vendor/automattic/jetpack-status/src/class-visitor.php

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Automattic\Jetpack\Status;
99

10+
use Automattic\Jetpack\IP\Utils as IP_Utils;
11+
1012
/**
1113
* Visitor class.
1214
*/
@@ -15,12 +17,40 @@ class Visitor {
1517
/**
1618
* Gets current user IP address.
1719
*
20+
* Only a value that parses as an IP address is returned. With `$check_all_headers`, the
21+
* forwarded headers are tried in order, a comma-separated list yields its first valid entry,
22+
* and a header holding no valid address is skipped.
23+
*
24+
* A site with a trusted header configured does not use that sweep at all. Brute force
25+
* protection stores which header carries the visitor address, how far back to count in its
26+
* list, and whether that list runs in reverse, all worked out for this site's own proxy
27+
* setup. Once that answer exists it is the answer, including when the request did not carry
28+
* the header — `IP\Utils::get_ip()` falls back to `REMOTE_ADDR` itself in that case. Reading
29+
* the sweep afterwards would let a request that simply omits the trusted header pick its own
30+
* address out of a header it fully controls, and would hand Jetpack two answers for one
31+
* request, since brute force protection resolves the same visitor through `IP\Utils`.
32+
*
33+
* That is a guarantee about which source is consulted, not about the address itself: it
34+
* still assumes the proxy named in the stored configuration rewrites the header. A request
35+
* reaching the origin directly can present that header itself.
36+
*
37+
* The address is normalized by `IP\Utils::clean_ip()`: it is lowercased, anything following an
38+
* " unless " separator is dropped, and a port suffix, IPv6 brackets, or an `::ffff:` IPv4
39+
* mapping are reduced to the bare address. Code comparing this value against a stored or
40+
* configured address should normalize that address the same way.
41+
*
1842
* @param bool $check_all_headers Check all headers? Default is `false`.
1943
*
20-
* @return string Current user IP address.
44+
* @return string Current user IP address, or an empty string if no valid address could be determined.
2145
*/
2246
public function get_ip( $check_all_headers = false ) {
2347
if ( $check_all_headers ) {
48+
$trusted_header_data = get_site_option( 'trusted_ip_header' );
49+
if ( isset( $trusted_header_data->trusted_header ) ) {
50+
$trusted_ip = IP_Utils::get_ip();
51+
return false !== $trusted_ip ? $trusted_ip : '';
52+
}
53+
2454
foreach ( array(
2555
'HTTP_CF_CONNECTING_IP',
2656
'HTTP_CLIENT_IP',
@@ -31,14 +61,21 @@ public function get_ip( $check_all_headers = false ) {
3161
'HTTP_FORWARDED',
3262
'HTTP_VIA',
3363
) as $key ) {
34-
if ( ! empty( $_SERVER[ $key ] ) ) {
35-
// @todo Some of these might actually be lists of IPs (e.g. HTTP_X_FORWARDED_FOR) or something else entirely (HTTP_VIA).
36-
return filter_var( wp_unslash( $_SERVER[ $key ] ) );
64+
if ( empty( $_SERVER[ $key ] ) ) {
65+
continue;
66+
}
67+
// Proxies append to the list, so the leftmost entry is the client.
68+
foreach ( explode( ',', (string) wp_unslash( $_SERVER[ $key ] ) ) as $candidate ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Each entry is validated by clean_ip() below.
69+
$ip = IP_Utils::clean_ip( $candidate );
70+
if ( false !== $ip ) {
71+
return $ip;
72+
}
3773
}
3874
}
3975
}
4076

41-
return ! empty( $_SERVER['REMOTE_ADDR'] ) ? filter_var( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
77+
$ip = empty( $_SERVER['REMOTE_ADDR'] ) ? false : IP_Utils::clean_ip( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- clean_ip() validates it.
78+
return false !== $ip ? $ip : '';
4279
}
4380

4481
/**

vendor/composer/installed.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
'automattic/jetpack-account-protection' => array(
2323
'pretty_version' => '0.3.7',
2424
'version' => '0.3.7.0',
25-
'reference' => '52d2c147230017861abc43396c8935f548c23c74',
25+
'reference' => 'ac23f87204cd8005e11b0545e844569217ac0218',
2626
'type' => 'jetpack-library',
2727
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-account-protection',
2828
'aliases' => array(),
@@ -31,7 +31,7 @@
3131
'automattic/jetpack-activity-log' => array(
3232
'pretty_version' => '0.2.5',
3333
'version' => '0.2.5.0',
34-
'reference' => '8e8f5de29284e7ccf158baaf7ac8378aad159ab4',
34+
'reference' => '08a0799143c37a0d11cbba4d26acc20ec740fbe2',
3535
'type' => 'jetpack-library',
3636
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-activity-log',
3737
'aliases' => array(),
@@ -40,7 +40,7 @@
4040
'automattic/jetpack-admin-ui' => array(
4141
'pretty_version' => '0.10.0-alpha.1787558568',
4242
'version' => '0.10.0.0-alpha1787558568',
43-
'reference' => 'b150ba889748fae8d5a026c0c90eb00bd700bc00',
43+
'reference' => 'fd82589373864a324f4589fd56271d0e3450d003',
4444
'type' => 'jetpack-library',
4545
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-admin-ui',
4646
'aliases' => array(),
@@ -58,7 +58,7 @@
5858
'automattic/jetpack-assets' => array(
5959
'pretty_version' => '4.4.11',
6060
'version' => '4.4.11.0',
61-
'reference' => 'b62eaf61d7e44e8162719308916c2de21c3943f5',
61+
'reference' => 'a3929163f1bfa33e653f49eeeb872c13902ac2f2',
6262
'type' => 'jetpack-library',
6363
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-assets',
6464
'aliases' => array(),
@@ -121,7 +121,7 @@
121121
'automattic/jetpack-connection' => array(
122122
'pretty_version' => '8.12.0-alpha.1787647592',
123123
'version' => '8.12.0.0-alpha1787647592',
124-
'reference' => 'dc535a320364f7efa26cbb566840f70c445c07d5',
124+
'reference' => '0e6513e7b75a6ce9b6e1ef65b12e4bfaa7dc4b95',
125125
'type' => 'jetpack-library',
126126
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-connection',
127127
'aliases' => array(),
@@ -166,7 +166,7 @@
166166
'automattic/jetpack-jitm' => array(
167167
'pretty_version' => '4.3.52',
168168
'version' => '4.3.52.0',
169-
'reference' => 'f63913664cc896359fe88ba77b84b63ce0fb64b8',
169+
'reference' => '934016c22c3a669076ae0aca553ef02677e0f4ea',
170170
'type' => 'jetpack-library',
171171
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-jitm',
172172
'aliases' => array(),
@@ -202,7 +202,7 @@
202202
'automattic/jetpack-my-jetpack' => array(
203203
'pretty_version' => '5.44.1-alpha.1787571237',
204204
'version' => '5.44.1.0-alpha1787571237',
205-
'reference' => '52520a77f46f2a781a87c85cb786b082800b62e2',
205+
'reference' => '95f283fe59de2fd629795c7a5c6faf95164fd9bd',
206206
'type' => 'jetpack-library',
207207
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-my-jetpack',
208208
'aliases' => array(),
@@ -220,7 +220,7 @@
220220
'automattic/jetpack-plans' => array(
221221
'pretty_version' => '0.12.0',
222222
'version' => '0.12.0.0',
223-
'reference' => 'da6109e0be22db290022db06ff33ee6f8b1b78c1',
223+
'reference' => 'a50004a0c57e9e103ea0934ffbafdafa5093ba7e',
224224
'type' => 'library',
225225
'install_path' => __DIR__ . '/../automattic/jetpack-plans',
226226
'aliases' => array(),
@@ -229,7 +229,7 @@
229229
'automattic/jetpack-plugins-installer' => array(
230230
'pretty_version' => '0.5.11',
231231
'version' => '0.5.11.0',
232-
'reference' => 'fb773d64770a3fe0c0d6f71efa03b0bb5f2589a5',
232+
'reference' => 'cabcabf0379fa5e1f46521b763c8ab17a6510d8d',
233233
'type' => 'jetpack-library',
234234
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-plugins-installer',
235235
'aliases' => array(),
@@ -265,7 +265,7 @@
265265
'automattic/jetpack-redirect' => array(
266266
'pretty_version' => '3.0.15',
267267
'version' => '3.0.15.0',
268-
'reference' => '695017d7d4e5b8a3ad4ec6140348f3fc6126e86a',
268+
'reference' => '75d5b67a21d383025188fe50da29d6f34dac41dc',
269269
'type' => 'jetpack-library',
270270
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-redirect',
271271
'aliases' => array(),
@@ -281,9 +281,9 @@
281281
'dev_requirement' => false,
282282
),
283283
'automattic/jetpack-status' => array(
284-
'pretty_version' => '6.4.0',
285-
'version' => '6.4.0.0',
286-
'reference' => '3ffa2b5a87b5806706e37b53f5044fc0b376c40a',
284+
'pretty_version' => '6.5.0-alpha.1787650008',
285+
'version' => '6.5.0.0-alpha1787650008',
286+
'reference' => '38c3eb8978eee1e58f441eb9bf57d5126ffd7c33',
287287
'type' => 'jetpack-library',
288288
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-status',
289289
'aliases' => array(),
@@ -292,7 +292,7 @@
292292
'automattic/jetpack-sync' => array(
293293
'pretty_version' => '4.45.4',
294294
'version' => '4.45.4.0',
295-
'reference' => 'c6cada5883c4f4ce648571bf6c6e15beff37e56e',
295+
'reference' => '91d03ec69f32f9715a2e7115349b900d5f244e8d',
296296
'type' => 'jetpack-library',
297297
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-sync',
298298
'aliases' => array(),
@@ -310,7 +310,7 @@
310310
'automattic/jetpack-waf' => array(
311311
'pretty_version' => '0.28.11',
312312
'version' => '0.28.11.0',
313-
'reference' => '7b922bf175644c26c4d6c0cca14a4e7951867009',
313+
'reference' => '18531dddba7d2f1c7b15f40396785c1d5410746c',
314314
'type' => 'jetpack-library',
315315
'install_path' => __DIR__ . '/../../jetpack_vendor/automattic/jetpack-waf',
316316
'aliases' => array(),

vendor/composer/jetpack_autoload_classmap.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@
383383
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-constants/src/class-constants.php'
384384
),
385385
'Automattic\\Jetpack\\CookieState' => array(
386-
'version' => '6.4.0.0',
386+
'version' => '6.5.0.0-alpha1787650008',
387387
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-cookiestate.php'
388388
),
389389
'Automattic\\Jetpack\\Current_Plan' => array(
@@ -399,7 +399,7 @@
399399
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-device-detection/src/class-user-agent-info.php'
400400
),
401401
'Automattic\\Jetpack\\Errors' => array(
402-
'version' => '6.4.0.0',
402+
'version' => '6.5.0.0-alpha1787650008',
403403
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-errors.php'
404404
),
405405
'Automattic\\Jetpack\\ExPlat' => array(
@@ -411,7 +411,7 @@
411411
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-explat/src/class-rest-controller.php'
412412
),
413413
'Automattic\\Jetpack\\Files' => array(
414-
'version' => '6.4.0.0',
414+
'version' => '6.5.0.0-alpha1787650008',
415415
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-files.php'
416416
),
417417
'Automattic\\Jetpack\\Heartbeat' => array(
@@ -479,7 +479,7 @@
479479
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-menu-badges/src/class-notification-counts.php'
480480
),
481481
'Automattic\\Jetpack\\Modules' => array(
482-
'version' => '6.4.0.0',
482+
'version' => '6.5.0.0-alpha1787650008',
483483
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-modules.php'
484484
),
485485
'Automattic\\Jetpack\\My_Jetpack\\Historically_Active_Modules' => array(
@@ -635,7 +635,7 @@
635635
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-password-checker/src/class-password-checker.php'
636636
),
637637
'Automattic\\Jetpack\\Paths' => array(
638-
'version' => '6.4.0.0',
638+
'version' => '6.5.0.0-alpha1787650008',
639639
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-paths.php'
640640
),
641641
'Automattic\\Jetpack\\Plans' => array(
@@ -723,23 +723,23 @@
723723
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-roles/src/class-roles.php'
724724
),
725725
'Automattic\\Jetpack\\Status' => array(
726-
'version' => '6.4.0.0',
726+
'version' => '6.5.0.0-alpha1787650008',
727727
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-status.php'
728728
),
729729
'Automattic\\Jetpack\\Status\\Cache' => array(
730-
'version' => '6.4.0.0',
730+
'version' => '6.5.0.0-alpha1787650008',
731731
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-cache.php'
732732
),
733733
'Automattic\\Jetpack\\Status\\Host' => array(
734-
'version' => '6.4.0.0',
734+
'version' => '6.5.0.0-alpha1787650008',
735735
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-host.php'
736736
),
737737
'Automattic\\Jetpack\\Status\\Request' => array(
738-
'version' => '6.4.0.0',
738+
'version' => '6.5.0.0-alpha1787650008',
739739
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-request.php'
740740
),
741741
'Automattic\\Jetpack\\Status\\Visitor' => array(
742-
'version' => '6.4.0.0',
742+
'version' => '6.5.0.0-alpha1787650008',
743743
'path' => $baseDir . '/jetpack_vendor/automattic/jetpack-status/src/class-visitor.php'
744744
),
745745
'Automattic\\Jetpack\\Sync\\Actions' => array(

0 commit comments

Comments
 (0)