views:

102

answers:

3

I just wanted to run this by other heads to make sure I wasn't missing something obvious. I am using Payflow Link, which handles all the credit card nastiness of ecommerce transactions. However, you pass the total amount of the transaction to PayPal over POST variables - which seems like a potential security hole:

  1. A malicious user could load up his cart and proceed to checkout
  2. By reading the hidden input fields, he could spoof the POST to PayPal with a total amount of 1 cent.
  3. Paypal would executes the transaction, calls my order logging script, which would log the transaction and mark his items for shipment.

I could check total amount against his cart by accessing the database, pulling his cart items, and re-totaling their prices plus shipping and tax. But that is a lot of heavy lifting just to check for tampering (multiple DB queries, plus 2 web service calls per item to get shipping and tax).

My idea:

  1. PayPal is sent the normal POST variables for the amount
  2. But then, in the user defined variables (which get forwarded to my logging script), store a sha1 hash of the total amount, plus some private key
  3. On the other side, the logging script rehashes the dollar amount, plus the same private key, and compares to the hash sent through.
  4. Differences between the sent hash and computed hash would indicate tampering, and the order would be red-flagged for human review.

Does this make sense? Am I missing something?

edit (for clarification):

Apparently I wasn't making my point clear, based on the first several responses. I realize this isn't an ideal setup. I know other companies offer similar or possibly even better services. I know I have to check the variables and I can't simply trust them. Please, if you are going to reply, all I am looking for in an answer is this:

Can anyone demonstrate a single vulnerability with my proposal that would allow a malicious user to alter the PayPal variables and go undetected?

It is a very straightforward question. That is all I am looking for. To anyone who can answer that, thank you in advance for you time and help!

+2  A: 

You need to do a manual check after IPN for the calculated amount using your DB details and then verify it with the amount paid in PayPal. There is really no other option and I strongly suggest you do this or users will try and game the system.

You can use this guide to encrypt your PayPal variables:

http://dev.juokaz.com/php/paypal-payment-with-encryption

Alec Smart
Can you provide any specific examples of how my system could be "gamed"? You haven't really explained why there is no other option. Also, the guide you linked to is for PayPal Website Payments Standard. I am using Payflow Link, which, as far as I can tell, doesn't offer the encrypted option discussed on your link.
Dave W.
A: 

I've seen such hacking with my own eyes. Some dude bought a $500 gift card for like $1. We quickly added code that compares order totals from IPN to our own data and marks the order as suspicious when they do not match.

Payflow Link description says: "You decide whether or not to settle the transaction". So you must check if the amount is correct every time.

Ilya Vassilevsky
This answer does not help at all. All I am asking is if the setup I am suggesting would foil attempts to tamper with the amount charged, or if there is some hole in my security logic. I think you are suggesting that I need to go back and query the database to check the values. If so, why does my proposal not work? Can anyone give me a single example a hack? I really don't understand why my question is so difficult to understand.
Dave W.
Sorry for that. What I wanted to convey is that you must save the order amount in your own database somehow BEFORE sending anything to PayPal. When PayPal then sends you an IPN, it contains the order amount that was actually processed. Then your script must compare the two values.
Ilya Vassilevsky
The best protection is of course processing all payments in the background, through Website Payments Pro.
Ilya Vassilevsky
Once again, just like I stated in my original comment: you haven't provided a single way my setup could be vulnerable. Simply stating "your script must compare the two values" is not a solid argument as to why my less-intensive method is not secure. And yes, I realize there are more secure methods, as I have stated in my edits to the original question, and comments to other answers. But this is the setup I have to work with, so I need to figure out a solution to this problem.
Dave W.
+2  A: 

One potential problem I can see is using the same salt every time when generating the SHA-1 hash. If you use the same salt every time, the attacker could very easily determine the hash for $0.99 (or some other low amount) and then substitute that in for any transaction they want to pay $0.99 for.

Edit: Obviously this problem holds if you come up with some algorithm for determining a salt. If that algorithm is broken somehow, your attacker could exploit that as well.

CanSpice
Thank you! I realized this might have been a problem. My knowledge of hashing is limited, but wouldn't you need a very large dataset to crack it? Also, wouldn't an algorithmically produced salt be exponentially harder to crack (i.e. the attacker could determine the salt perhaps, but then also has to crack the algorithm to produce the salt?). Thanks again for the first useful answer!
Dave W.
With a variable (and unguessable) salt, yeah, you'd need a large dataset to crack it. The trouble comes in the verification, because you need to somehow replicate the salt twice. If you're using some time-variable salt, then you can't really calculate it when you're doing the verification, because it'll change and you'll get a different hash out. I guess you could store the salt in a database, along with some unique identifier for the transaction, then pull that out when you do the verification step... But that could be insecure too, depending on how you store it...
CanSpice
Online commerce is wrought with difficulties, in other words, and it's usually not a good idea to roll your own solution when others have been widely tested and work well, like PayPal Pro or Cybersource.
CanSpice