PayPal Buy Now Button Security
Good PayPal Button Security Starts With You
Paypal is a very popular online payment processor that allows almost anyone to send and receive money online. It was made popular as a payment platform by eBay user in the late 90's and rose in general popularity with eBay and beyond eBay as it is used on many sites online. Paypal provides html code that allows users to place customizable purchase buttons on their own websites to sell both tangible and intangible goods and services. With most html coding and client side rendering, the payment information associated with a payment button is easily viewable by anyone who decides to view the source of the webpage containing the payment button.
At the bottom of this page you will be able to download a working Buy Now Button Script to you use on your website with 1 product. The script does require php.
What's At Risk In Your PayPal Button
Let's look at this sample PayPal Buy Now Button Code:
Some of the payment information viewable from the Paypal purchase button are the price, item name, seller email address, price, and currency just to name a few. Now these variables in themselves are not a huge security risk, outside of the potential unsolicited email that may be received if an someone copies your email address from the html source code. If you are selling a tangible good or service, you would naturally check that payment has been received in full before fulfilling an order or service. The safety of this type of payment button lies with the seller who will verify payment before fulfilling the order. This is a pretty secure setup, however it starts to get a little sketchy when you are dealing with intangible goods.
Intangible Goods and PayPal Buttons
Now lets take a look at a typical Buy Now Button code used to sell an intangible good:
As with the previous button code there are variables that are viewable such as the price, seller email, item name, and currency. There is also additional variables that may be included to facilitate routing buyers to either a purchased download if payment is made or back to a different page on the sellers site if the payment is cancelled. These variables, return and cancel_return serve the purpose of routing the customer.
The main problem with the purchase buttons comes into play when a person is selling an intangible good. The nature of selling intangible goods such as ebooks or software, is that file delivery needs to occur rather quickly after payment is received. This is a good practice as a merchant and is very good customer service because a customer that receives what they paid for instantly is less likely to panic and be suspicious of their purchase.
This instant delivery of intangible goods is handled by a website script or the paypal button itself. Usually the download link is placed on the 'Thank You' page or return URL, that the buyer is sent to by Paypal after payment has been completed. I hope you can see the security issue inherit with this sort of system. The return URL, as I mentioned earlier, is viewable in the html code, so a buyer could easily just look at your code on your page and see the return URL and go directly to that page and get the ebook or software for free.
That's how PayPal Buy Now buttons were compromised in the past. I say the past because I think and hope that most merchants have corrected this fault by having a mechanism in place that checks to make sure that the buyer came to the 'Thank You' page directly from PayPal. Now we have the entire PayPal button security issue solved. Wrong, we are not even close to protecting our ebooks and software. While some webmasters have implemented the recommended mechanism to check that the buyer was sent to the download page by PayPal, it's really not enough protection.
How Do You Get Ripped Off?
When a someone with bad intentions discovers that going directly to your Thank You page (return url), doesn't allow free access to the download because they went there directly without going to PayPal, they have just received a valuable piece of information about your security scheme. So what does a resourceful bad guy do?
The resourceful bad guy will do 1 of 2 things to circumvent your PayPal button security.
They will use your button to start to make a payment. This will set a session cookie on their computer that can be read by your site to show that a buying session has taken place. But instead of actually completing the purchase, they go straight from PayPal to your return url and get your best selling ebook for free.
How does this happen?
Some of the mechanism schemes that I mentioned earlier to determine if a buyer was sent to the return by PayPal is the use of session cookies. While cookies is beyond the scope of this lens, I'll tell you specifically how the session cookies by PayPal communicate with a sellers website. The buying session cookie will only be set by PayPal when a purchase is initiated. Unfortunately, a purchase does not have to be completed for the buying session cookie to remain active in the users browser. Some webmasters check for the referring page and/or the buying session cookie to verify that the seller came from PayPal. While the referrer can't easily be faked, the buying session cookie can be generated without payment.
This one is far more popular and if you are not careful you will get robbed blind by this. Instead of pretending to make a payment for your best selling ebook, the thief actually does make a payment for far less than the price you set (usually 1 cent). Paypal will accept the payment and send the buyer to get their copy of your ebook. The thing here is that PayPal doesn't do price checking, so it doesn't know if your ebook is selling for $100.00 USD or $0.01 USD. PayPal will accept the price that is sent for the product and will use all the variables included in the button code. To add insult to injury some bad guys even change the seller email address in the button code and you won't even get a penny for your download. Once again because PayPal is only going to check that the recipient email address is a valid PayPal account and process the payment and all button code variables as normal. That makes this cheat very effective for sites that do not properly protect their PayPal Buttons.
How does this happen?
It's easy to view and copy the button from a webpage just by viewing the source, and that's what a thief will do. They will copy your button code and put it on their website, except that they will change the price to something like 0.01 to get your download for a penny. The thief will also change the return and cancel_return variables like this:
The thief has to add your full domain name, so that Paypal will redirect them to the correct return after payment, otherwise the original button code would send the bad guy to a 'thank_you.htm' page on their own website.
While both of these methods are used, the most dangerous one is option 2 because it behaves exactly like a legitimate purchase even though you are getting massively shortchanged.
How To Protect Your Buy Now Buttons?
You can not really stop anyone from attempting and pulling off Option 1 or 2 from above. Option 1 can not be stopped because PayPal is responsible for the session cookie, your only hope is to implement a better means of checking the return variables supplied by PayPal. Option 2 can not be stopped because it is a legitimate payment (even if it's an underpayment) and you can not stop anyone from copying your button code.
That is the nature of security (rather a lack of security) in a client side browsing environment. Client side meaning processes and functions that take place on the users local machine and directly within their browser. True security lies server side. Server side meaning the processes and functions that take place remotely on the server of the website the user is visiting. Server side implementation prevents unauthorized access by client side methods.
Server side functions require the use of scripts such as .php to handle the dynamic content and to make decisions based on the data that is submitted. HTML can not be used for server side functions because HTML is static and is basically just rendered output for the browser, where PHP can process data and output HTML to the browser.
What a good webmaster will do to protect their intangible goods from thieves is to disregard the referrer checking and session cookie checking in favor of their own built in payment checking. I personally like to redirect my PayPal Buy Now buttons to my own website to check that all variables are accurate (and change them if they are not) before sending the buyer to PayPal.
So the flow of a buyer making a purchase via my buy now button would be:
1. Buyer clicks the button and is not sent to https://www.paypal.com/cgi-bin/webscr from the button code. Instead they are sent to something like http://www.mysite.com/paypal_verify.php.
2. Once at the http://www.mysite.com/paypal_verify.php page, I have my paypal_verify.php script check the actual price and seller email, and make the corrections where necessary. The return and cancel_return variables are changed to the actual values and are not viewable by the buyer before completing their purchase. The price, seller email, return, and cancel_return are stored in the paypal_verify.php page itself.
3. Once the price and seller email have been verified or updated, I automatically send the buyer to PayPal using a new Buy Now button that is dynamically generated and automatically submits to PayPal. This creates a seamless experience for the buyer and they arrive at PayPal ready to pay the correct amount to the correct seller.
This internal price checking ensures that even if a thief creates their own PayPal button, they will have to go through my paypal_verify.php page for verification before being sent to PayPal. Even if the thief changes the price on the button, it will be corrected before they reach PayPal.
A secured button code using this scheme might look something like this:
(You can omit this line all together)
(You can omit this line all together)
(You can omit this line all together)
(You can omit this line all together)
An even more secured button code would look something like this:
Because we are sending the price, seller email, return, and cancel_return variable from our own script, we can leave these lines out of the button code and let our script create this for us. This makes sure that the payment amount is correct and is paid to the correct person and that the return URL is correct after the payment has been received. All of which makes for a pretty secure payment flow at least at the beginning of the transaction.
I know that you are your thinking that the Buy Now Button is finally bulletproof. Well it is...sort of. The one flaw with this system is that the user is sent to the return url after payment. For a buyer that has never made a purchase through your site it's not a big deal, but for a thief that may decide to make a legitimate small payment to find your return page, it can pose a problem. Once the thief has your correct return url, they can go back to creating their own Buy Now buttons and have them submit directly to PayPal and return to your correct return url. Yes it will cost money to get this information, but once they have this info, they can take you to the cleaners.
Don't get discouraged, I still recommend this protection scheme because we are going to protect the download next in a similar way.
Securing The Intangible Goods
Since we protected the Buy Now button, by creating the button stocked with the correct variables dynamically, we should definitely protect our download by checking that the payment has been received and that the amount is correct. PayPal returns these variable when the buyer is returned to your site. You just need to specify how you would like the variables returned.
Within your return url, lets call it thank_you.php, you will need to implement price checking of the download before a download link is exposed to the buyer. If the prices do not match up, give them an error message. It's as simple as that. Most thieves will not try to get a refund for a penny for an attempted fraudulent purchase, otherwise they open themselves up to being investigated by PayPal. Feel free to refund the money (you should do this, even if the thief does not deserve it) and then report the thief to PayPal and let them know that this person has attempted to steal your product by underpaying through PayPal Buy Now button manipulation.
User Friendly Flow Of Payment
By doing all these methods, you are checking the price before the buyer goes to PayPal and checking the price after the buyer returns from PayPal. This creates a bulletproof way to sell intangible goods with instant delivery. The example above refers to checking the variables sent from PayPal when the user is routed to your sites return URL, and is dependent on your user being able to follow directions to click the link to return to get their download.
A word of advice, do not leave it up to the buyer. You do not know their reading level, intelligence level, or ability to follow simple directions. A more elegant solution is to use Instant Payment Notification. With Instant Payment Notification, you can ensure that the payment has been made correctly and that the download will be delivered, by allowing PayPal to communicate directly with your server on a server side basis. This takes the user out of this type of flow and is far more reliable and offers the ability to do better transaction management.
Download My Buy Now Button Script
Now that you understand the logic behind protecting your PayPal Buttons and Intangible Goods by intercepting the payment flow and validating the returned variables, I'm going to give you a sample script that you are free to modify and use on your own sites.
I just updated this file and added an additional file to the script that give curl() support for those whose webhosting gives them trouble with the regular fsockopen() function of communicating with PayPal. This script should now give everyone maximum compatibility. This script has not been tested on windows based hosting at all, only Unix/Linux based webhosting has been tested.
This script comes with instructions and supports the selling of a single product. This file may not be resold without my permission (please respect this request, thanks).
Here is the download link to the script (it's in a .zip file):