English 中文(简体)
How can I detect if the user is on localhost in PHP?
原标题:

In other words, how can I tell if the person using my web application is on the server it resides on? If I remember correctly, PHPMyAdmin does something like this for security reasons.

最佳回答

You can use $_SERVER[ REMOTE_ADDR ], which contains the IP address of the client requesting it, as given by the web server.

$whitelist = array(
     127.0.0.1 ,
     ::1 
);

if(!in_array($_SERVER[ REMOTE_ADDR ], $whitelist)){
    // not valid
}

Note: the original version of this answer suggested verifying the destination hostname using $_SERVER[ HTTP_HOST ], which is unsafe because it could in some cases be spoofed by the requester.

问题回答

As a complement, as a function...

function isLocalhost($whitelist = [ 127.0.0.1 ,  ::1 ]) {
    return in_array($_SERVER[ REMOTE_ADDR ], $whitelist);
}

Newer OS users (Win 7, 8) may also find it necessary to include an IPV6-format remote address in their whitelist array:

$whitelist = array( 127.0.0.1 , "::1");

if(!in_array($_SERVER[ REMOTE_ADDR ], $whitelist)){
    // not valid
}

I m sorry but all these answers seem terrible to me. I would suggest rephrasing the question because in a sense all machines are "localhost".

The question should be; How do I run different code paths depending on which machine it is executed on.

In my opinion, the easiest way is to create a file called DEVMACHINE or whatever you want really and then simply check

file_exists( DEVMACHINE )

Remember to exclude this file when uploading to the live hosting environment!

This solution is not depending on network configuration, it can not be spoofed and makes it easy to switch between running "live-code" and "dev-code".

$_SERVER["REMOTE_ADDR"] should tell you the user s IP. It s spoofable, though.

Check this bounty question for a very detailed discussion.

I think what you remember with PHPMyAdmin is something different: Many MySQL Servers are configured so that they can only be accessed from localhost for security reasons.

It doesn t seem you should use $_SERVER[ HTTP_HOST ], because this is the value in http header, easily faked.

You may use $_SERVER["REMOTE_ADDR"] too, this is the more secure value, but it is also possible to fake. This remote_addr is the address where Apache returns result to.

Used this simple PHP condition

if($_SERVER[ HTTP_HOST ] ==  localhost )
{
    die( Localhost );
}

If you want to have a whitelist / allowlist that supports static IPs and dynamic names.

For example:

$whitelist = array("localhost", "127.0.0.1", "devel-pc.ds.com", "liveserver.com");
if (!isIPWhitelisted($whitelist)) die();

This way you could set a list of names/IPs that will be able (for sure) to be detected. Dynamic names add more flexibility for accessing from different points.

You have two common options here, you could set a name in your local hosts file or you could just use one dynamic name provider that could be found anywhere.

This function CACHES results because gethostbyname is a very slow function.

For this pupose I ve implemented this function:

function isIPWhitelisted($whitelist = false)
{
    if ( isset($_SESSION) && isset($_SESSION[ isipallowed ]) )
        { return $_SESSION[ isipallowed ];  }

    // This is the whitelist
    $ipchecklist = array("localhost", "127.0.0.1", "::1");
    if ($whitelist) $ipchecklist = $whitelist;

    $iplist = false;
    $isipallowed = false;

    $filename = "resolved-ip-list.txt";
    $filename = substr(md5($filename), 0, 8)."_".$filename; // Just a spoon of security or just remove this line

    if (file_exists($filename))
    {
        // If cache file has less than 1 day old use it
        if (time() - filemtime($filename) <= 60*60*24*1)
            $iplist = explode(";", file_get_contents($filename)); // Read cached resolved ips
    }

    // If file was not loaded or found -> generate ip list
    if (!$iplist)
    {
        $iplist = array(); $c=0;
        foreach ( $ipchecklist as $k => $iptoresolve )
        {
            // gethostbyname: It s a VERY SLOW function. We really need to cache the resolved ip list
            $ip = gethostbyname($iptoresolve);
            if ($ip != "") $iplist[$c] = $ip;
            $c++;
        }

        file_put_contents($filename, implode(";", $iplist));
    }

    if (in_array($_SERVER[ REMOTE_ADDR ], $iplist)) // Check if the client ip is allowed
        $isipallowed = true;

    if (isset($_SESSION)) $_SESSION[ isipallowed ] = $isipallowed;

    return $isipallowed;
}

For better reliability you could replace the $_SERVER[ REMOTE_ADDR ] for the get_ip_address() that @Pekka mentioned in his post as "this bounty question"

How about to compare $_SERVER[ SERVER_ADDR ] === $_SERVER[ REMOTE_ADDR ] to determine if client is on the same machine as server?

Also there is another easy way to check is localhost or not: this code check if ip is in private or reserved range if it is thene we are in localhost.

  • support ipv4 & ipv6.
  • support ip range like 127.0.0.1 - 127.255.255.255

PHP Code:

function is_localhost() {

    $server_ip = null;

    if ( defined(  INPUT_SERVER  ) && filter_has_var( INPUT_SERVER,  REMOTE_ADDR  ) ) {
        $server_ip = filter_input( INPUT_SERVER,  REMOTE_ADDR , FILTER_VALIDATE_IP );
    } elseif ( defined(  INPUT_ENV  ) && filter_has_var( INPUT_ENV,  REMOTE_ADDR  ) ) {
        $server_ip = filter_input( INPUT_ENV,  REMOTE_ADDR , FILTER_VALIDATE_IP );
    } elseif ( isset( $_SERVER[ REMOTE_ADDR ] ) ) {
        $server_ip = filter_var( $_SERVER[ REMOTE_ADDR ], FILTER_VALIDATE_IP );
    }

    if ( empty( $server_ip ) ) {
        $server_ip =  127.0.0.1 ;
    }

    return empty( filter_var( $server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE ));
}
  1. for get ip i use filter_input to avoid ip injection in code by user.
  2. in some case filter_input not supported in CGI scripts so if not exist i get ip in normal way with $_SERVER var.
  3. FILTER_VALIDATE_IP And FILTER_FLAG_NO_PRIV_RANGE are documented in php site you can find more information in this link.




相关问题
Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

定值美元

如何确认来自正确来源的数字。

Generating a drop down list of timezones with PHP

Most sites need some way to show the dates on the site in the users preferred timezone. Below are two lists that I found and then one method using the built in PHP DateTime class in PHP 5. I need ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

热门标签