Question

In my website, I've integrated a php script that receive an IPN notification and send a license key to the customer. This script is in a folder with other 2 php files required by the php script... How can I protect this folder? If I place in it an .htaccess with:

order allow,deny
deny from all

I block the paypal notifications too.

How can I protect it? Do I need to?

Was it helpful?

Solution

You can safely limit access to your IPN script only to the following list of IP addresses:

216.113.188.202
216.113.188.203
216.113.188.204
66.211.170.66

This can be done in the following way:

if (!in_array($_SERVER['REMOTE_ADDR'],array('216.113.188.202','216.113.188.203','216.113.188.204','66.211.170.66')) {
header("HTTP/1.0 404 Not Found");
exit();
}

In this way ONLY Paypal will be able to access the IPN script.

This list of IP address has been rather stable for years. In case if Paypal adds a new address, you can add reporting to email and review such cases manually.

OTHER TIPS

There are many things you can do:

  1. Give your script an obscure name so that it is not easily guessable.
  2. Disable directory listings in the folder
  3. Check if the calling site is paypal.com (or related IP address etc.)

why you are trying to do this?

in IPN system, you first just bounce the variables that are passed to your ipn script back to paypal using cURL or fshock or what ever... looking into the response you can tell if it's a valid transaction or not... someone can not fake a transaction variable that does not exists in paypal itself... all they can do is to reuse an older transaction info again to fool your script.. since it exists on paypal your script will be assuming that it's a successfull payment...

so you can prevent this just by comparing txn_id against your database and if already exists in your database this means someone is trying to fool you using an already recorded transaction info...

since you do those checks who cares about the ones that call this ipn script... it wont be working for them since you check the variables against paypal and your database...

in any exceptions print out a nice sentence to tell them "This script is robust! Dont Try to fool us!"

If you know the IP from which PayPal will use the script try:

order deny, allow
deny from all
allow from [Paypal-IP]

I wouldn't recommend shutting out all IPs, since you can't be sure that Paypal will keep the requests coming from the same IP all the time. If they ever decide to change their IP range, your setup will break, probably without notification to you.

I think the script that processes the Paypal request is the place to handle this - in that script you need to make sure that the request is actually coming from Paypal. You can do this by using some obscure URL that isn't easily guessed as has been suggested.

If at all possible, look into the shared secret setup for IPN - this way you have a better way of checking that the request is actually coming from Paypal, although it is a bit harder to set up.

Hope this helps!

Check out the go live checklist:

https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_api_golivechecklist

(Developer Home > How to > API > Go Live Checklist)

for a list of ip address to allow

Now I've do this:

in the folder where is stored the php script and the 2 configuration files I've created an other folder where I moved the 2 config files and where I've placed a .htaccess with the following code:

order allow,deny
deny from all

Now the 2 config files have a good protection! ... but not the script that receive the notifications! If I try to block the directory listing( for the folder that contains the php script and the config folder) with:

IndexIgnore *

The paypal sandbox gives me an error 500!

So the only thing that I can do to protect the script is to place, on the head of it, a condition that verify the notifications come from paypal.com ?

Finally I've added on head of the php script an if statement based on the remote host name:

 $remote_host = gethostbyaddr($_SERVER['REMOTE_ADDR']);

if someone is interested, it's also possible to query $_SERVER['REMOTE_HOST'] but must be configured the httpd.conf file on the server.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top