PayPal IPN Security
paypal, paypal-ipn, php, security
Solution
I know this question is quite old, but:
The attacker does not even need to spoof his ip or perform any sort of MITM to pass your validation:
- He connects from his own machine with IP address x.y.z.t.
- Your server calls gethostbyaddr("x.y.z.t") which sends a dns query for the name t.z.y.x.in-addr.arpa.
- If x.y.z.t belongs to the attacker, chances are he controls (at least) the dns domain z.y.x.in-addr.arpa as well (since that contains his own ip). So he can return "paypal.com" in response to that query.
- Your server receives "paypal.com" from the attacker's dns server, and your validation check succeeds.
This attack is defeated by sending a request to paypal as recommended by Lobos.
Problem
PayPal IPN sends a POST request with a variable number of fields to the notify URL, in order to confirm that the POST request is legit we need to resubmit the same request along with a additional `cmd=_notify-validate` field to PayPal, which then replies `VERIFIED` or `INVALID`. My question is, why do we need to resend the request to PayPal? Wouldn't something like this suffice? ``` if (preg_match('~^(?:.+[.])?paypal[.]com$~i', gethostbyaddr($_SERVER['REMOTE_ADDR'])) > 0) { // request came from PayPal, it's legit. } ``` Iff we can trust the server to correctly resolve IPs, I assume we can trust all requests from PayPal, no?