views:

164

answers:

3

I have a PayPal IPN PHP file set up which assigns all of the IPN post contents variables to variables. This file is only 'hit' from paypal.com (ie nobody should know it's url).

My question is should I take the necessary steps to filter and sanitize the POST data from PayPal or is masking my IPN file name (IPN_082j3f08jasdf.php) enough?

Also, could somebody confirm my sanitize code? It's pretty basic. I run it on EVERYTHING sent via POST or GET and my goal is to prevent any kind of MySQL injections or whatever hackers do.

function filter($data){
 // changes & to &
 // changes " to "
 // removes \ < >

 $data = trim(htmlentities(strip_tags($data)));

 if(get_magic_quotes_gpc()){
  $data = stripslashes($data);
 }
 $data = mysql_real_escape_string($data);

 return $data;
}
+1  A: 

You may also consider using more robust filtration mechanism used also by Kohana php framework which can be found here:

http://svn.bitflux.ch/repos/public/popoon/trunk/classes/externalinput.php

Sarfraz
that looks like overkill...
ina
@ina: Not overkill for famouse kohana framework :)
Sarfraz
So, would you recommend that I use the Kohana sanitize function over my relatively small one for a site who's pretty much only inputs are from form POSTs and url GETs? (no file uploader or any crazy applets). Hah, sorry, I'm just hesitant to insert such a massive piece of code all throughout my site.
Derek
@Derek: It isn't that massive, the decision is yours, however i personally use that :)
Sarfraz
+2  A: 

obfuscating the filename is never enough -- you need to filter the POST data, yes. Assume it is not PayPal calling the script until you can prove it.

the sanitation looks OK -- if your code becomes quite long though, I would tend to sanitize it in two steps --the strip_tags and basic sanitation at the beginning, and the mysql escaping at the same time you contact the database -- it makes it easier to maintain IMO.

Jhong
if the filename is totally obscure, how would anyone find it?
ina
If someone found a way to get a directory listing, the file's name wouldn't help it much.
cHao
@Ina, remember, the security is only as strong as the weakest link, which could be another script on your server -- it is often fairly trivial to hunt around on a target server to get it to expose more information about itself, including file names and indexes (directory listings).
Jhong
ok, but how do they get to the directory listing if it's not another script on the server?
ina
@ina: Taking advantage of a misconfiguration of the server, a script on another site on the server...a stupidly placed non-anonymous FTP link...there are a number of potential ways, if someone's so inclined to check for them.
cHao
A: 

Sorry for the bad advice! Please disregard this post! - keeping it undeleted, as it's generated some interesting discussion below

If no one should know its URL, the SQL-sanitize is probably not that big of an issue. Masking your IPN file should be enough unless someone hijacks your directory listing.

htmlentities() will need to have an ENT_QUOTES flag to convert quotes.

if get_magic_quotes_gpc() is on, then strip_slashes are automatically done... in your case, it looks like you will double strip slashes.

also mysql_real_escape_string will do the work of strip_slashes() already ...

ina
If magic quotes are on, slashes are **added** automatically -- and need to be stripped, lest they end up causing \\\\\\\\\\\\\\\\\\\ stuff like that.
cHao
Security by obscurity is not security. The IPN API provides ways to verify that an IPN is from Paypal; USE IT. If the IPN is from Paypal, then it's probably safe -- Paypal isn't in the habit of hacking its users' sites.
cHao
`mysql_real_escape_string` and `stripslashes` do almost, *but not quite*, **opposite** things. `mysql_real_escape_string` adds slashes (in a way that always works for mysql, unlike `addslashes`), and `stripslashes` *removes them*.
cHao
`htmlentites` doesn't need `ENT_QUOTES` unless you're escaping single quotes with it. The default is to escape double quotes, and leave single quotes alone.
cHao
@cHao: "The IPN API provides ways to verify that an IPN is from Paypal" - How? So is there a way to say 'if(from_paypal)'?
Derek
@Derek: You post all the POST variables back to Paypal, and add "cmd=notify-validate" or something like that. The server's response will tell you whether the post was valid (made by Paypal) or not. The sample code from Paypal includes this check (albeit a bit uglily done). In any PHP wrapper around the web API, there may indeed already be an `is_valid_ipn()` or similar function.
cHao
@Derek: See the sample code at https://cms.paypal.com/cms_content/US/en_US/files/developer/IPN_PHP_41.txt .
cHao
Got it, works. Thanks!
Derek