Link to home
Start Free TrialLog in
Avatar of gg26gg26
gg26gg26

asked on

spoofing $REMOTE_ADDR protection

Hi all,

I have a php based site that users log into using a username and password. They can only access the site from a certain location which I use $REMOTE_ADDR to check this as this location has a fixed IP.

I have been warned that it is easy to spoof this $REMOTE_ADDR variable, which from what I head read on various sites seems to be the case.

Has anyone got any tips that I could use to prevent a user from spoofing their IP to make the system think they are at the specific location?
Sorry, I'm waffling, how can I protect my site against spoofed $REMOTE_ADDR variables?

Thanks in advance

Avatar of Richard Davis
Richard Davis
Flag of United States of America image

Well, you can never truly prevent such types of attacks as it's easier to become someone else than it is to detect that an identity isn't real.
One approach that does offer a little better clarity of the "truth" factor though would be to check the ip within each of these contexts;

      //get the ip of the client
      $client_ip = ( !empty($HTTP_SERVER_VARS['REMOTE_ADDR']) ) ? $HTTP_SERVER_VARS['REMOTE_ADDR'] : ( ( !empty($HTTP_ENV_VARS['REMOTE_ADDR']) ) ? $HTTP_ENV_VARS['REMOTE_ADDR'] : getenv('REMOTE_ADDR') );

then work against this derived IP address, but I too have to prevent such things on an e-card site that I developed and the only real form of protection I have been able to come to depend on is a random character image generator for human validation of the use of my forms, but other than that, about the only thing you would really have left would be to go 100% SSL/TLS as this demands a number of higher level handshakes to take place that a spoofer would never be able to duplicate without a super computer and a few million hours of solid hacking.

I hope this offered you some help though.

Good luck :)

~Adrian
SOLUTION
Avatar of Muhammad Wasif
Muhammad Wasif
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gg26gg26
gg26gg26

ASKER

Hi Adrian & Wasifq,

Thanks for the info. My entire site runs over 128 bit ssl and they also require a username and login. The site is setup so that 5 concurrent invalid entries for a correct username will lock that account.

My problem is that we give access to this site to certain members of staff in the office, but I need to prevent them from logging in from other places. I cannot use time frames as they work different hours, so using IP seems to be my best bet.

Sorry to sound dense here, but which of the 2 suggested code snippets would you seem to be most robust and would you mind telling me that they are actually doing better than just grabbing the $REMOTE_ADDR. Sorry, but I'm not too hot on server vars. Have read a bit on them, but I dont seem to get the differences.

Thanks
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
When someone spoof REMOTE_ADDR/use proxy, then HTTP_X_FORWARDED_FOR contains his IP. This is what i have observed.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi,

Many thanks for all your help, It sounds like there is not a way to spoof REMOTE_ADDR, but to actaully bounce your traffic from another source (ie proxy or compromised PC). Seeing as my app is set to only allow logins from a single IP (which is an always on braodband fixed IP) spoofing this by menas of a proxy is going to be almost impossible seeing as return packets would surely go to the real fixed IP.

It also sounds like as a "bold and braces", I should give the option for each account to validate the IP using HTTP_X_FORWARDED_FOR, so that if switched on it checks both the HTTP_X_FORWARDED_FOR and REMOTE_ADDR (I realise ths wont work for all users AOL springs to mind), but for my purpose this would provide a double check.

Do you guys think I've understood what you have all been suggesting or have I missed something. Knowing that I understand the above means I can actually better understand the solution.

A reply to this would be appreciated so I know i'm not barking up the wrong tree

Thanks
Sorry to keep asking, have tried the variables on 2 different connected systems

$ip1=$_SERVER['HTTP_X_FORWARDED_FOR'];
$ip2=$_SERVER['REMOTE_ADDR'];
$ip3=$HTTP_SERVER_VARS['REMOTE_ADDR'];

I get the same IP for $ip2 and $ip3, but do not get anything on either systems for $IP1.
1 system is a commercial inernet provider, the other is tiscali.

Any ideas why $ip1 is returning nothing???

Thanks again
Your understanding of spoofing sounds about right, if somebody tried to spoof the single IP that is allowed then it would fail because packets would go back to that IP, which wouldn't know what to do with them (as it didn't originate the connection).

HTTP_X_FORWARDED_FOR will only be set if a (well-behaved) proxy is being used. Do you know for sure that one of the two systems you tested with uses a proxy?

Is your app designed to only allow logins from a single IP overall (i.e. "the" office) or is it a different IP for each user?
Normally just the office, however some other users may also have a fixed IP that they can only login from. The IP that is allows is based on a user by user so this not a global list of accepted IP's.
As far as I am aware, neither of the 2 system runs proxy's. Is there a way I can test that the value would be obtained if a user was running a proxy?

Can I assume that you cannot spoof just the REMOTE_ADDR variable, but still have the traffic route to your actual IP?

Thanks for all your help
REMOTE_ADDR is set by the webserver based on the IP address it received the request from. The webserver will also reply to this same IP address.

The only way I can think of for REMOTE_ADDR to contain something different to the IP address the request came from, would be if you had some badly written code that changed it somewhere, e.g.

$_SERVER['REMOTE_ADDR'] = 'some.fake.ip.address';

// now REMOTE_ADDR won't contain the original address. obviously.

There are less obvious examples though, e.g. badly written register_globals emulations, which might allow global variables to be overwritten. You'd know if you were using one of these though...

As for testing, assuming you don't have a proxy available... most of the free/public proxies are designed for anonymity and tend to withhold the X-Forwarded-For: header - not much use since this is what you're looking for!

At a push you could try using Coral (free content distribution network), it's not really designed for this but it will provide a proxied connection with the right headers. To do this, append .nyud.net:8080 to the host part of your URL, so for example:

http://www.mysite.com/path/to/file.php

becomes

http://www.mysite.com.nyud.net:8080/path/to/file.php

The request will come from a different IP address, and your real address should appear in $_SERVER['HTTP_X_FORWARDED_FOR'].

I have a nasty feeling you'll run into problems putting this much emphasis on IP-based restrictions though - sooner or later you'll either get a legitimate user who lives behind a proxy that *doesn't* provide X-Forwarded-For:, or a non-legitimate (illegitimate? :P) user who figures out how to spoof the header.

I suppose the first of those isn't too big a deal, you could let the proxy itself through since the user needs a username/password to do anything useful anyway.

Hope all that makes sense!
Hi,

The comments were most useful. It sounds like just checking the REMOTE_ADDR seems to be the best way to check. If this is a spoofed address using a proxy, it will only be the proxy address anyway and not the IP the system is looking for.
If an attempt is made to get the proxy to mimic the required IP, from what you are saying my web server will reply to the legitimate IP anyway as its a fixed IP and not to the spoofing proxy.

Have I summed this up correctly?, or is there any point in checking the x-forwarded-for??

Tried your nyud test which worked a treat.

Thanks for the replies.
Neither the proxy nor any clients can mimic the IP address unless they can receive packets sent by the server back to that IP address.

So anyone connecting to your server must either be the legitimate owner of the IP address they're connecting from, or in a position to snoop on/redirect traffic to that IP address.
Hi All,

many thanks for all your comments and suggestions.

I have equaled the points as best I can to all involved.

Sincerest thanks again to all.