Skip to content

Spoofing possible when no proxy is used #6

@pierre-vigier

Description

@pierre-vigier

To get the client IP for 'X-Forwarded-for', we need to trust the proxy that did set that header.

If the application is behind a owned proxy, 'X-Forwarded-for' is setup by a trust worthy proxy, the plugin works fine.
If a Client try to spoof its IP address by putting a value in the 'X-Forwarded-for' header, it will still work as expected:
client IP : 1.1.1.1
proxy IP : 10.10.10.10
The application will see: remote_address: 10.10.10.10 , X-Forwarded-for: 1.1.1.1 -> the plugin will return 1.1.1.1, which is fine
if the client now try to add 9.9.9.9 as X-Forwarded-for,
The application will see: remote_address: 10.10.10.10 , X-Forwarded-for: 1.1.1.1,9.9.9.9 -> the plugin will still return 1.1.1.1, which is fine

If the application is not behind a reverse proxy, the following will happen:
client IP : 1.1.1.1
The application will see: remote_address: 1.1.1.1 , X-Forwarded-for is empty -> the plugin will return 1.1.1.1, which is fine
if the client now try to add 9.9.9.9 as X-Forwarded-for,
The application will see: remote_address: 1.1.1.1 , X-Forwarded-for: 9.9.9.9 -> the plugin will return 9.9.9.9, which is wrong

Running the Readme exemple, show the problem (i purposely remove 192.168.0.0/16 from the private one, to "simulate" a public exposed application, on public IP).

use Mojolicious::Lite;
 
plugin 'ClientIP' => private => [qw(127.0.0.0/8 10.0.0.0/8)];
 
get '/' => sub {
    my $c = shift;
    $c->render(text => $c->client_ip);
};
 
app->start;
carton exec morbo app.pl -l http://\*:5555
» http http://192.168.1.101:5555
HTTP/1.1 200 OK
Content-Length: 9
Content-Type: text/html;charset=UTF-8
Date: Wed, 29 Jul 2020 03:13:26 GMT
Server: Mojolicious (Perl)

192.168.1.101

» http :5555 'X-forwarded-for':'9.9.9.9'
HTTP/1.1 200 OK
Content-Length: 7
Content-Type: text/html;charset=UTF-8
Date: Wed, 29 Jul 2020 03:13:22 GMT
Server: Mojolicious (Perl)

9.9.9.9

In the second case, as the caller set the x-forwarded-for itself, it's not trusted, nor private, it should not be returned. On solution to fix that would be to prepend the remote_address to the @candidates. in that case, the remote_address would have been 192.168.1.101, which is already untrusted, hence, the X-forwarded-for should not be considered

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions