View | Details | Raw Unified | Return to bug 25950
Collapse All | Expand All

(-)a/Koha/Middleware/RealIP.pm (-1 / +2 lines)
Lines 81-89 sub get_real_ip { Link Here
81
81
82
    my $trusted_proxies = get_trusted_proxies();
82
    my $trusted_proxies = get_trusted_proxies();
83
83
84
    #X-Forwarded-For: <client>, <proxy1>, <proxy2>
85
    my $real_ip = shift @forwarded_for;
84
    my @unconfirmed = ( @forwarded_for, $remote_addr );
86
    my @unconfirmed = ( @forwarded_for, $remote_addr );
85
87
86
    my $real_ip;
87
    while (my $addr = pop @unconfirmed) {
88
    while (my $addr = pop @unconfirmed) {
88
        my $has_matched = 0;
89
        my $has_matched = 0;
89
        foreach my $netmask (@$trusted_proxies) {
90
        foreach my $netmask (@$trusted_proxies) {
(-)a/t/Koha/Middleware/RealIP.t (-55 / +89 lines)
Lines 20-26 Link Here
20
20
21
use strict;
21
use strict;
22
use warnings;
22
use warnings;
23
use Test::More tests => 13;
23
use Test::More tests => 10;
24
use Test::Warn;
24
use Test::Warn;
25
25
26
use t::lib::Mocks;
26
use t::lib::Mocks;
Lines 28-89 use_ok("Koha::Middleware::RealIP"); Link Here
28
28
29
my ($remote_address,$x_forwarded_for_header,$address);
29
my ($remote_address,$x_forwarded_for_header,$address);
30
30
31
$remote_address = "1.1.1.1";
31
subtest "No X-Forwarded-For header" => sub {
32
$x_forwarded_for_header = "";
32
    plan tests => 1;
33
$address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
33
    $remote_address = "1.1.1.1";
34
is($address,'1.1.1.1',"There is no X-Forwarded-For header, so just use the remote address");
34
    $x_forwarded_for_header = "";
35
36
$remote_address = "1.1.1.1";
37
$x_forwarded_for_header = "2.2.2.2";
38
$address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
39
is($address,'1.1.1.1',"Don't trust 1.1.1.1 as a proxy, so use it as the remote address");
40
41
$remote_address = "1.1.1.1";
42
$x_forwarded_for_header = "2.2.2.2";
43
t::lib::Mocks::mock_config('koha_trusted_proxies', '1.1.1.1');
44
$address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
45
is($address,'2.2.2.2',"Trust proxy (1.1.1.1), so use the X-Forwarded-For header for the remote address");
46
47
48
$remote_address = "1.1.1.1";
49
$x_forwarded_for_header = "2.2.2.2,3.3.3.3";
50
t::lib::Mocks::mock_config('koha_trusted_proxies', '1.1.1.1 3.3.3.3');
51
$address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
52
is($address,'2.2.2.2',"Trust multiple proxies (1.1.1.1 and 3.3.3.3), so use the X-Forwaded-For <client> portion for the remote address");
53
54
$remote_address = "1.1.1.1";
55
$x_forwarded_for_header = "2.2.2.2,3.3.3.3";
56
t::lib::Mocks::mock_config('koha_trusted_proxies', 'bad configuration');
57
warnings_are {
58
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
35
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
59
} ["could not parse bad","could not parse configuration"],"Warn on misconfigured koha_trusted_proxies";
36
    is($address,'1.1.1.1',"There is no X-Forwarded-For header, so just use the remote address");
60
is($address,'1.1.1.1',"koha_trusted_proxies is misconfigured so ignore the X-Forwarded-For header");
37
};
38
39
subtest "No configuration" => sub {
40
    plan tests => 1;
41
    $remote_address = "2.2.2.2";
42
    $x_forwarded_for_header = "1.1.1.1";
43
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
44
    is($address,'2.2.2.2',"No trusted proxies available, so don't trust 2.2.2.2 as a proxy, instead use it as the remote address");
45
};
46
47
subtest "Bad configuration" => sub {
48
    plan tests => 4;
49
    $remote_address = "1.1.1.1";
50
    $x_forwarded_for_header = "2.2.2.2,3.3.3.3";
51
    t::lib::Mocks::mock_config('koha_trusted_proxies', 'bad configuration');
52
    warnings_are {
53
        $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
54
    } ["could not parse bad","could not parse configuration"],"Warn on misconfigured koha_trusted_proxies";
55
    is($address,'1.1.1.1',"koha_trusted_proxies is misconfigured so ignore the X-Forwarded-For header");
56
57
    $remote_address = "1.1.1.1";
58
    $x_forwarded_for_header = "2.2.2.2";
59
    t::lib::Mocks::mock_config('koha_trusted_proxies', 'bad 1.1.1.1');
60
    warning_is {
61
        $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
62
    } "could not parse bad","Warn on partially misconfigured koha_trusted_proxies";
63
    is($address,'2.2.2.2',"koha_trusted_proxies contains an invalid value but still includes one correct value, which is relevant, so use X-Forwarded-For header");
64
};
65
66
subtest "Fail proxy isn't trusted" => sub {
67
    plan tests => 1;
68
    $remote_address = "2.2.2.2";
69
    $x_forwarded_for_header = "1.1.1.1";
70
    t::lib::Mocks::mock_config('koha_trusted_proxies', '3.3.3.3');
71
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
72
    is($address,'2.2.2.2',"The 2.2.2.2 proxy isn't in our trusted list, so use it as the remote address");
73
};
74
75
subtest "Success one proxy" => sub {
76
    plan tests => 1;
77
    $remote_address = "2.2.2.2";
78
    $x_forwarded_for_header = "1.1.1.1";
79
    t::lib::Mocks::mock_config('koha_trusted_proxies', '2.2.2.2');
80
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
81
    is($address,'1.1.1.1',"Trust proxy (2.2.2.2), so use the client IP from the X-Forwarded-For header for the remote address");
82
};
61
83
62
$remote_address = "1.1.1.1";
84
subtest "Success multiple proxies" => sub {
63
$x_forwarded_for_header = "2.2.2.2";
85
    plan tests => 1;
64
t::lib::Mocks::mock_config('koha_trusted_proxies', 'bad 1.1.1.1');
86
    $remote_address = "2.2.2.2";
65
warning_is {
87
    $x_forwarded_for_header = "1.1.1.1,3.3.3.3";
88
    t::lib::Mocks::mock_config('koha_trusted_proxies', '2.2.2.2 3.3.3.3');
66
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
89
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
67
} "could not parse bad","Warn on partially misconfigured koha_trusted_proxies";
90
    is($address,'1.1.1.1',"Trust multiple proxies (2.2.2.2 and 3.3.3.3), so use the X-Forwaded-For <client> portion for the remote address");
68
is($address,'2.2.2.2',"koha_trusted_proxies contains an invalid value but still includes one correct value, which is relevant, so use X-Forwarded-For header");
91
};
69
92
70
$remote_address = "1.1.1.1";
93
subtest "Test alternative configuration styles" => sub {
71
$x_forwarded_for_header = "2.2.2.2";
94
    plan tests => 3;
72
t::lib::Mocks::mock_config('koha_trusted_proxies', '1.1.1.0/24');
95
    $remote_address = "2.2.2.2";
73
$address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
96
    $x_forwarded_for_header = "1.1.1.1";
74
is($address,'2.2.2.2',"Trust proxy (1.1.1.1) using CIDR notation, so use the X-Forwarded-For header for the remote address");
97
    t::lib::Mocks::mock_config('koha_trusted_proxies', '2.2.2.0/24');
75
98
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
76
$remote_address = "1.1.1.1";
99
    is($address,'1.1.1.1',"Trust proxy (2.2.2.2) using CIDR notation, so use the X-Forwarded-For header for the remote address");
77
$x_forwarded_for_header = "2.2.2.2";
100
78
t::lib::Mocks::mock_config('koha_trusted_proxies', '1.1.1');
101
    $remote_address = "2.2.2.2";
79
$address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
102
    $x_forwarded_for_header = "1.1.1.1";
80
is($address,'2.2.2.2',"Trust proxy (1.1.1.1) using abbreviated notation, so use the X-Forwarded-For header for the remote address");
103
    t::lib::Mocks::mock_config('koha_trusted_proxies', '2.2.2');
81
104
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
82
$remote_address = "1.1.1.1";
105
    is($address,'1.1.1.1',"Trust proxy (2.2.2.2) using abbreviated notation, so use the X-Forwarded-For header for the remote address");
83
$x_forwarded_for_header = "2.2.2.2";
106
84
t::lib::Mocks::mock_config('koha_trusted_proxies', '1.1.1.0:255.255.255.0');
107
    $remote_address = "2.2.2.2";
85
$address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
108
    $x_forwarded_for_header = "1.1.1.1";
86
is($address,'2.2.2.2',"Trust proxy (1.1.1.1) using an IP address and netmask separated by a colon, so use the X-Forwarded-For header for the remote address");
109
    t::lib::Mocks::mock_config('koha_trusted_proxies', '2.2.2.0:255.255.255.0');
110
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
111
    is($address,'1.1.1.1',"Trust proxy (2.2.2.2) using an IP address and netmask separated by a colon, so use the X-Forwarded-For header for the remote address");
112
};
113
114
subtest "Client IP is properly processed even if it is in koha_trusted_proxies" => sub {
115
    $remote_address = "1.1.1.2";
116
    $x_forwarded_for_header = "1.1.1.1";
117
    t::lib::Mocks::mock_config('koha_trusted_proxies', '1.1.1.0/24');
118
    $address = Koha::Middleware::RealIP::get_real_ip( $remote_address, $x_forwarded_for_header );
119
    is($address,'1.1.1.1',"The X-Forwarded-For value matches the koha_trusted_proxies, but there is no proxy specified");
120
    done_testing(1);
121
};
87
122
88
subtest "IPv6 support" => sub {
123
subtest "IPv6 support" => sub {
89
    my ($remote_address,$x_forwarded_for_header,$address);
124
    my ($remote_address,$x_forwarded_for_header,$address);
90
- 

Return to bug 25950