@@ -127,24 +127,16 @@ fn get_ua(
127
127
None
128
128
}
129
129
130
- fn is_trusted_proxy ( proxy_list : & [ IpNet ] , host : & str ) -> Result < bool , HandlerError > {
131
- // Return if an address is NOT part of the allow list
132
- let test_addr: IpAddr = match host. parse ( ) {
133
- Ok ( addr) => addr,
134
- Err ( e) => return Err ( HandlerErrorKind :: BadRemoteAddrError ( format ! ( "{:?}" , e) ) . into ( ) ) ,
135
- } ;
136
- for proxy_range in proxy_list {
137
- if proxy_range. contains ( & test_addr) {
138
- return Ok ( true ) ;
139
- }
140
- }
141
- Ok ( false )
130
+ fn is_trusted_proxy ( proxy_list : & [ IpNet ] , host : & IpAddr ) -> bool {
131
+ // Return if an address is part of the allow list
132
+ proxy_list. iter ( ) . any ( |range| range. contains ( host) )
142
133
}
143
134
144
135
fn get_remote (
145
136
peer : & Option < SocketAddr > ,
146
137
headers : & http:: HeaderMap ,
147
138
proxy_list : & [ IpNet ] ,
139
+ log : & logging:: MozLogger ,
148
140
) -> Result < String , HandlerError > {
149
141
// Actix determines the connection_info.remote() from the first entry in the
150
142
// Forwarded then X-Fowarded-For, Forwarded-For, then peer name. The problem is that any
@@ -156,31 +148,36 @@ fn get_remote(
156
148
if peer. is_none ( ) {
157
149
return Err ( HandlerErrorKind :: BadRemoteAddrError ( "Peer is unspecified" . to_owned ( ) ) . into ( ) ) ;
158
150
}
159
- let peer_ip = peer. unwrap ( ) . ip ( ) . to_string ( ) ;
151
+ let peer_ip = peer. unwrap ( ) . ip ( ) ;
160
152
// if the peer is not a known proxy, ignore the X-Forwarded-For headers
161
- if !is_trusted_proxy ( proxy_list, & peer_ip) ? {
162
- return Ok ( peer_ip) ;
153
+ if !is_trusted_proxy ( proxy_list, & peer_ip) {
154
+ return Ok ( peer_ip. to_string ( ) ) ;
163
155
}
164
156
165
157
// The peer is a known proxy, so take rightmost X-Forwarded-For that is not a trusted proxy.
166
158
match headers. get ( HeaderName :: from_lowercase ( "x-forwarded-for" . as_bytes ( ) ) . unwrap ( ) ) {
167
159
Some ( header) => {
168
160
match header. to_str ( ) {
169
161
Ok ( hstr) => {
162
+ info ! ( log. log, "Remote IP List: {:?}" , hstr) ;
170
163
// successive proxies are appeneded to this header.
171
164
let mut host_list: Vec < & str > = hstr. split ( ',' ) . collect ( ) ;
172
165
host_list. reverse ( ) ;
173
166
for host_str in host_list {
174
- let host = host_str. trim ( ) . to_owned ( ) ;
175
- if !is_trusted_proxy ( proxy_list, & host) ? {
176
- return Ok ( host. to_owned ( ) ) ;
167
+ match host_str. trim ( ) . parse :: < IpAddr > ( ) {
168
+ Ok ( addr) => {
169
+ if !addr. is_loopback ( ) &&
170
+ !is_trusted_proxy ( proxy_list, & addr) {
171
+ return Ok ( addr. to_string ( ) ) ;
172
+ }
173
+ } ,
174
+ Err ( err) => {
175
+ return Err ( HandlerErrorKind :: BadRemoteAddrError ( "Bad IP Specified" . to_owned ( ) ) . into ( ) ) ;
176
+ }
177
177
}
178
- }
179
- Err ( HandlerErrorKind :: BadRemoteAddrError ( format ! (
180
- "Could not find remote IP in X-Forwarded-For"
181
- ) )
182
- . into ( ) )
183
- }
178
+ } ;
179
+ Err ( HandlerErrorKind :: BadRemoteAddrError ( "Only proxies specified" . to_owned ( ) ) . into ( ) )
180
+ } ,
184
181
Err ( err) => Err ( HandlerErrorKind :: BadRemoteAddrError ( format ! (
185
182
"Unknown address in X-Forwarded-For: {:?}" ,
186
183
err
@@ -302,6 +299,7 @@ impl From<HttpRequest<WsChannelSessionState>> for SenderData {
302
299
& req. peer_addr ( ) ,
303
300
& req. headers ( ) ,
304
301
& req. state ( ) . trusted_proxy_list ,
302
+ & log,
305
303
) {
306
304
Ok ( addr) => Some ( addr) ,
307
305
Err ( err) => {
@@ -485,30 +483,31 @@ mod test {
485
483
486
484
let true_remote: SocketAddr = "1.2.3.4:0" . parse ( ) . unwrap ( ) ;
487
485
let proxy_server: SocketAddr = "192.168.0.4:0" . parse ( ) . unwrap ( ) ;
486
+ let log = logging:: MozLogger :: new_human ( ) ;
488
487
489
488
bad_headers. insert (
490
489
http:: header:: HeaderName :: from_lowercase ( "x-forwarded-for" . as_bytes ( ) ) . unwrap ( ) ,
491
490
"" . parse ( ) . unwrap ( ) ,
492
491
) ;
493
492
494
493
// Proxy only, no XFF header
495
- let remote = get_remote ( & Some ( proxy_server) , & empty_headers, & proxy_list) ;
494
+ let remote = get_remote ( & Some ( proxy_server) , & empty_headers, & proxy_list, & log ) ;
496
495
assert ! ( remote. is_err( ) ) ;
497
496
498
497
// Proxy only, bad XFF header
499
- let remote = get_remote ( & Some ( proxy_server) , & bad_headers, & proxy_list) ;
498
+ let remote = get_remote ( & Some ( proxy_server) , & bad_headers, & proxy_list, & log ) ;
500
499
assert ! ( remote. is_err( ) ) ;
501
500
502
501
// Proxy only, crap XFF header
503
502
bad_headers. insert (
504
503
http:: header:: HeaderName :: from_lowercase ( "x-forwarded-for" . as_bytes ( ) ) . unwrap ( ) ,
505
504
"invalid" . parse ( ) . unwrap ( ) ,
506
505
) ;
507
- let remote = get_remote ( & Some ( proxy_server) , & bad_headers, & proxy_list) ;
506
+ let remote = get_remote ( & Some ( proxy_server) , & bad_headers, & proxy_list, & log ) ;
508
507
assert ! ( remote. is_err( ) ) ;
509
508
510
509
// Peer only, no header
511
- let remote = get_remote ( & Some ( true_remote) , & empty_headers, & proxy_list) ;
510
+ let remote = get_remote ( & Some ( true_remote) , & empty_headers, & proxy_list, & log ) ;
512
511
assert_eq ! ( remote. unwrap( ) , "1.2.3.4" . to_owned( ) ) ;
513
512
514
513
headers. insert (
@@ -517,7 +516,7 @@ mod test {
517
516
) ;
518
517
519
518
// Peer proxy, fetch from XFF header
520
- let remote = get_remote ( & Some ( proxy_server) , & headers, & proxy_list) ;
519
+ let remote = get_remote ( & Some ( proxy_server) , & headers, & proxy_list, & log ) ;
521
520
assert_eq ! ( remote. unwrap( ) , "1.2.3.4" . to_owned( ) ) ;
522
521
523
522
// Peer proxy, ensure right most XFF client fetched
@@ -526,7 +525,7 @@ mod test {
526
525
"1.2.3.4, 2.3.4.5" . parse ( ) . unwrap ( ) ,
527
526
) ;
528
527
529
- let remote = get_remote ( & Some ( proxy_server) , & headers, & proxy_list) ;
528
+ let remote = get_remote ( & Some ( proxy_server) , & headers, & proxy_list, & log ) ;
530
529
assert_eq ! ( remote. unwrap( ) , "2.3.4.5" . to_owned( ) ) ;
531
530
532
531
// Peer proxy, ensure right most non-proxy XFF client fetched
@@ -535,7 +534,7 @@ mod test {
535
534
"1.2.3.4, 2.3.4.5, 192.168.0.10" . parse ( ) . unwrap ( ) ,
536
535
) ;
537
536
538
- let remote = get_remote ( & Some ( proxy_server) , & headers, & proxy_list) ;
537
+ let remote = get_remote ( & Some ( proxy_server) , & headers, & proxy_list, & log ) ;
539
538
assert_eq ! ( remote. unwrap( ) , "2.3.4.5" . to_owned( ) ) ;
540
539
}
541
540
}
0 commit comments