PHP only show form if user is connecting from specific IP - php

On my site I have the ability for users to send a message to me. It's stored just in a mysql database.
The url is something like: www.mysite.com/contact?id=4ijr3943jwswER4we (some random hash on the end as the id)
I have/had the ability that if I go to this url and view the message, then an input box shows and it allows only me to reply to the message directly from that page. It does this by checking if the IP that the user is connecting from is my ip.
I've found that my IP is dynamic and thus whenever my ip gets reassigned, I'm no longer able to see this input form (since I'm now connecting from a different IP).
Is there a way (apart from setting a static IP on my machine) to achieve this same goal? Obviously checking the IP isn't going to be a long term solution, and I've read that you can't grab a users MAC address either.
If it matters, here's the code I've got for checking the IP:
function getClientIP() {
$ipaddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
}
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else if(isset($_SERVER['HTTP_X_FORWARDED'])) {
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
}
else if(isset($_SERVER['HTTP_FORWARDED_FOR'])) {
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
}
else if(isset($_SERVER['HTTP_FORWARDED'])) {
$ipaddress = $_SERVER['HTTP_FORWARDED'];
}
else if(isset($_SERVER['REMOTE_ADDR'])) {
$ipaddress = $_SERVER['REMOTE_ADDR'];
}
else {
$ipaddress = 'UNKNOWN';
}
return $ipaddress;
}
And it is checked by:
if((getClientIP() == "::1" || getClientIP() == "<my ip>") {
// show an input box and submit button
}
Thanks!

Ignoring the blatant disregard security and the fact that I would fire someone for doing this but you could have a &admin=$value in the url. Something like this.
function is_admin() {
$password = filter_input(INPUT_GET, "password", FILTER_SANITIZE_EMAIL);
if ($password == "abc123") {
return TRUE;
} else {
return FALSE;
}
}
so you can replace getClientIP() with is_admin()
if(is_admin()) {
// show an input box and submit button
}
and then call it like this.
http://www.example.com/contact?id=4ijr3943jwswER4we&admin=abc123
again, this is a horribly insecure solution and you should be using a PKI with ssh port forwarding a VPN connection but this works but I'm a sucker for an easy 10 point answer.

You might try using a free dynamic DNS service. Set up a domain, such as "MINE.COM", and use that instead of your IP. When your IP changes, the dynamic DNS service is supposed to adjust, so that MINE.COM is changed to point to the new IP. Your site can check the client for MINE.COM instead of the IP.
Be warned there is a lag time involved. It could be minutes or hours before "MINE.COM" reflects the updated IP. Plus, most "free" services involve advertising which might render your setup unusable.
Bottom line, without a static IP, you're pretty much hosed. A static IP is certainly possible, but usually costs more, as generally only larger concerns like schools, governments or businesses want or need one.
I suggest you investigate using an alternate method, such as a login form, passwords, sessions, cookies, etc. E.g., login as your admin account, establish a cookie on your device, then the next time you visit the site, it can authenticate your device's cookie.

Related

php currency setting based on user location

I need to change currency based on user location. This is my code
<?php
$ipaddress = $_SERVER['REMOTE_ADDR'];
$location = unserialize( file_get_contents('http://www.geoplugin.net/php.gp?ip=' . $_SERVER['REMOTE_ADDR']) );
if($location["geoplugin_countryCode"] === "US")
{
// block to set us currency
}
else{
// user can choose their own currency from array (excluding us)
}
?>
I uploaded it on a server, and to check if the functionality works correctly or not and I used different vpn chrome extension. The problem is all the time else part is alone gets executed even when I choose us as vpn server. I don't know What is causing this problem.
Most probably the issue is that you use $_SERVER['REMOTE_ADDR'].
If you are using a proxy, you should use $_SERVER['HTTP_X_FORWARDED_FOR']

$_SERVER['remote_addr'] returns a private ip address

I have a subscription to a pro offer at OVH. I think that the php environment isn't well configured because when I try to request the client IP with the environment it returns a private IP such as 10.X.X.X wich changes every refreshing.
I tried to print the entire environment to see if the public IP is stored anywhere else, but it is not.
Have you got any ideas where it might comes from ?
Thanks.
seems like you are testing from your localhost. On your live server, the ip address should be properly displayed. Here is a simple function to further assist you:
function getUserIpAddress() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}

"Do not Access Superglobal $_SERVER Array Directly" on Netbeans 7.4 for PHP

Yes, a similar question was posted and answered correctly.
Warning "Do not Access Superglobal $_POST Array Directly" on Netbeans 7.4 for PHP
That post was helpful. but it did not resolve my problem.
I am not getting any OUTPUT in my browser.
I applied all of the options exchanging $_POST with $_SERVER.
My original code:
$user_ip = $_SERVER[ 'REMOTE ADDR'];
My code modified several ways as the other question/ answer suggests
user_ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR');
user_ip = filter_input_array(INPUT_SERVER, 'REMOTE_ADDR');
STILL NO OUTOUT
Background.
I am appending code after code in my index.php as I go thru these tutorials.
I keep commenting out the previous code.
I missed a few comments and at that point I actually DID HAVE OUTPUT
::1
What I expected as output was
127,0,0,1
When I commented the all of the code from the previous tutorial
I no longer get any output.
I am going thru a tutorial which is very good but he is using xampp.
I am on a Mac and installed amp.
Don't know if that matters.
If you want to take a look, navigate to
thenewboston.com
Tutorials
Php
Lesson 33
http://thenewboston.org/watch.php?cat=11&number=33
First minute or so in.
When PHP is FastCGI based,
filter_input(INPUT_SERVER,…
and
filter_input_array(INPUT_SERVER…
don't return any results!
See the PHP manual entry on filter_input, paying particular attention to the comment by anthony dot parsons
You can use $_SERVER directly and there is no need of use filter_input.The output ::1 is just because you are running this code on Localhost. If you try your code on server(check you code on RemoteHost) then it will give your cLient's IP. Here is my code for fetch the Client's I.P. See Snapshot Here
if ($_SERVER['HTTP_CLIENT_IP'])
{
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
}
else if($_SERVER['HTTP_X_FORWARDED_FOR'])
{
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else if($_SERVER['HTTP_X_FORWARDED'])
{
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
}
else if($_SERVER['HTTP_FORWARDED_FOR'])
{
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
}
else if($_SERVER['HTTP_FORWARDED'])
{
$ipaddress = $_SERVER['HTTP_FORWARDED'];
}
else if($_SERVER['REMOTE_ADDR'])
{
$ipaddress = $_SERVER['REMOTE_ADDR'];
}

Will the value of a set $_SERVER['HTTP_CLIENT_IP'] be an empty string?

I have a simple script which determines the user's IP address:
function GetIp(){
if (!empty($_SERVER['HTTP_CLIENT_IP']))
//check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
//to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
Now on the Net somewhere I saw someone using this script:
if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '')
$Ip = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '')
$Ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '')
$Ip = $_SERVER['REMOTE_ADDR'];
I was wondering if my implementation is broken.. Do I need to check if the value of $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'], or $_SERVER['REMOTE_ADDR'] is empty? Or is it actually unnecessary to do so?
If the reason why you want to find out the client's IP address is really important, screw all this stuff.
Any one of these header values can be freely spoofed.
REMOTE_ADDR is the only really reliable information, as it is transmitted to you by your web server that is handling the request. It can be theoretically falsified as well, but that is much, much harder than spoofing a header value, and an entirely different class of attack.
There are exceptions in very, very specific hosting environments behind reverse proxies. In those cases the person administering that proxy will be able to tell what header value you need to test for.
From Kohanas' Request class:
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
// Format: "X-Forwarded-For: client1, proxy1, proxy2"
$client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['HTTP_CLIENT_IP'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
$client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['REMOTE_ADDR']))
{
// The remote IP address
Request::$client_ip = $_SERVER['REMOTE_ADDR'];
}
This is pretty much as good as it gets. Please note the Request::$trusted_proxies array and that your $ip var is Request::$client_ip in this case.
Do not check any HTTP_* headers for the client IP unless you specifically know your application is configured behind a reverse proxy. Trusting the values of these headers unconditionally will allow users to spoof their IP address.
The only $_SERVER field containing a reliable value is REMOTE_ADDR.
The two things are practically identical.. In the script you found, the author is just doing a check if the element in the array is set before checking that it is non-empty.
In regards to using the empty()-function instead of the comparison, check http://php.net/empty. Since you are dealing with a variable that is set by the environment and not a user input it doesn't matter which of the two options you choose. So your script should be perfectly fine

Tracking email with PHP and image

I have seen the service like spypig.com placing a small image in the email and tracking when it is opened and from where. They track city, country, IP address etc. How is this done?
How do we know when the mail is opened? And how is the image
generated?
How is the IP address detected and how is it possible to know location from
it?
Basically, in the HTML body of your email, there will be an <img> tag that would look like this :
<img src="http://www.yoursite.com/tracker.php?id=123456" alt="" />
When someone reads his mail, with images enabled, the email-client will send a request to tracker.php, to load the image, passing it id=123456 as a parameter.
This tracker.php script will be on your server, and, when called, it will :
Check the id parameter,
Use it to find to which email address it corresponds -- when generating the email for each one of your subscribers, you'll have generated an id different for each e-mail.
Do some stuff -- like log "email 123456 has been opened", and some additional informations
return the content of a small image ; like a 1x1 transparent gif.
The tracker.php script knows from which IP address it's been called -- like any other PHP script :
$ipAddress = $_SERVER['REMOTE_ADDR'];
And, starting from this IP address, you can use a geolocation service to find out from where in the world the email has been opened.
As a couple of examples, you could take a look at MaxMind, or IPInfoDB
As you know that id=123456 corresponds to one specific email address, this allows to find out where each one of your subscribers are.
1. Place the tracker image at the E-mail
<img src="http://www.yoursite.com/tracker.php?eid=123456&uid=123" alt="" width="1px" height="1px">
Its working is very simple, Once your mail is open, that tracker image sends the request to the server, from that request we can get information by creating the image URL with userID, and also consider as that mail is read by the user.
Note: Don't use display: none; property for hiding your images, it may filter by spam algorithm. And don't place any javascript codes, it also blocks the spam filter
2. On the tracker.php
<?php
header("Content-Type: image/jpeg"); // it will return image
readfile("img.jpg");
dbfunction(); // place your db code
?>
3. The ip address is get by the following function.
function get_client_ip() {
$ipaddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress = $_SERVER['REMOTE_ADDR'];
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
$PublicIP = get_client_ip();
4. Location:
The location is getting by any geolocation services, you can use open-source GeoLocation finder like nekudo,freegeoip.
for example
<?php
$json = file_get_contents("http://ipinfo.io/$PublicIP/geo");
$json = json_decode($json ,true);
$country = $json['country_name'];
$region= $json['region_name'];
$city = $json['city'];
?>
The other answers are great but, since humanity seems convinced that "any tracking is evil tracking" I like to take it a step further by being "invisible" to the user by retaining the .png/.jpg/.gif etc image file extension.
I'm not sure about compatibility with all types of web servers and hosts, but for me it was a quick change to the AddHandler directive I already had in .htaccess, such as:
AddHandler application/x-httpd-lsphp .png
...to allow processing of PHP code within files with a .png extension.
You might already have an AddHandler line to allow PHP in .htm/.html files; if so, just add the appropriate image file extension to the end of the list.
This is, roughly, my "tracking image" code, file saved as trackimage.png or whatever :
<?php //silently log user and return image
$ip=$_SERVER['REMOTE_ADDR'];
$uri=tidy($_SERVER['SCRIPT_URI']);
$querystring=tidy($_SERVER['QUERY_STRING']);
$useragent=tidy($_SERVER['HTTP_USER_AGENT']);
$json = file_get_contents("https://ipinfo.io/".$ip."/geo");
if(($json<>'')&&(strpos($json,"error")===false)){ extract(json_decode($json ,true)); }
$country=tidy($country);
$prov=tidy($region);
$city=tidy($city);
list($lat,$lon)=explode(',',$loc);
$lat=tidy($lat);
$lon=tidy($lon);
$sql = "INSERT INTO img_track_table set ip='$ip', useragent=$useragent, uri=$uri, "
."querystring=$querystring, country=$country, prov=$prov, city=$city, lat=$lat, lon=$lon;";
require 'connect.php'; $conn=new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) { /* couldn't connect, but do nothing about it */ }
}else{ //run insert query
if(!$conn->query($sql)) { /* query error, but do nothing about it */ }
$conn->close();
}
//return image
header("Content-Type: image/png");
readfile("myActualImageFile.png");
function tidy($str){ //remove quotes and backslashes from string
if(is_null($str)||($str=="")){return "null";}
$str=trim(str_replace('\\','',str_replace("'","",str_replace('"',"",$str))));
if(is_numeric($str)){return $str;}
return "'$str'";
}
Note that if error text, or anything else, is returned by the code before the image, the image will be undisplayable. It might also be worth researching possible security concerns with this that might apply to you case. For example, this.
About the first part of the question, what I did was return the image from a PHP file. Aside from returning an image (it can be 1x1 pixel transparent png) is logging all the info into the database. This way, when the PHP file is called, you know that the image was loaded i.e. the email was read. The problem is that a lot of modern clients don't load images automatically. This is to not allow just the kind of thing you're trying to do, for privacy reasons.
About the second part, there are several geolocation web services, where you submit an IP and get the geolocation. You can do that in the PHP file that returns the 1x1 pixel image.
Here is a good thread about this on this site:
Geolocation web service recommendations

Categories