You are on page 1of 14

FightingOnlineFraudPitfalls

AndSolutions
Online payment fraud is rampant. Whether it is because
its easier to steal anonymously, or because tracking down
someone over the net and prosecuting them is difficult if
not impossible, online fraud hits everyone who takes
payments online.
The situation is even more problematic for digital products,
in which case credit-card companies or Paypal refuse to
provide any kind of seller protection. The reasoning behind
it is that digital product fraud does not result in actual
material loss, and its hard to prove delivery both are
false, but the situation stands as it is anyway.
As a marketplace for digital products, Binpress has been
hit by its share of online fraud. We used to accept both
Paypal and credit-card payments (through stripe), and
both have been abused in various ways.

Fraudmethods
Paypal
Paypal promotes itself as a more secure payment method
by removing the need to enter credit-card details online. In
reality, Paypal account credentials can be compromised
just as easily as credit-card details, and it still has the
vulnerability of credit-card payments (unless you disable
that feature).

Paypal can be abused in several ways, so lets go over the


main attack methods:
Paypal account hijacking
By getting a hold of Paypal account credentials or an
active logged-in session, an unauthorized user can make
payments using Paypal as if he were the real account
holder.
This route is very advantageous to the attacker he does
not have to pass all the checks banks employ on creditcard transactions (address, zipcode, CVC) and use the
account to pay immediately.
Paypal payments with stolen credit-card details
Paypal allows people without an account to pay directly
with a credit-card (unless you specifically disable that
option). This means that stolen credit-card details can be
used the same as with every credit-card payment option
(which will be covered in more detail in the next section).
Fortunately (or not), Paypal has its own fraud detection
mechanism that it uses on credit-card payments. This
means that credit-card payments on Paypal are less likely
to be stolen, but on the other hand Paypal often rejects
legit payments that fail their somewhat strict detection
system.
Paypal disputes on legit transactions
In a way, this is the most troublesome fraud of all. The
transaction itself will appear completely legit, as the
account owner in fact authorized it. What we deal here is

buyer remorse, where the buyer simply decides he does


not want to pay for the transaction, and opens a dispute
on Paypal.
Paypal will side with the buyer most of the time, unless
you can provide strong evidence of delivery (for example,
a sign-off on a shipping paper). To some degree, Paypal
will offer payment protection on certain products.
Unfortunately, digital goods are not included and Paypal
provides no guarantee of protection for those kind of
transactions.

Creditcardtransactions
Unauthorized transactions
An attacker will attempt to make an online payment by
getting a hold of credit-card information. The information
can start at only the card number, and extend to expiry
date, CVC and even address details.
Unfortunately, confirmation of credit-card details across
banks is very inconsistent. Some banks do not even check
the expiry date or the CVC security code (!), while others
might return a false positive (it wouldve been better if they
had returned not checked).
To make matters even worse, a bank might approve a
transaction even if some of the details were checked and
confirmed as incorrect. This attitude extends to some
payment gateways, which will leave the decision up to the
bank and will not deny a transaction if some of the security
checks are false. (We use Stripe by the way, which follows
this approach).
Chargebacks on legit transactionsSimilar to the Paypal

option, a person who paid with a credit-card can later


disavow his purchase by filling a chargeback with the
credit-card company. This process is worse than Paypals
disputes, with the cost usually higher and a much lower
chance of keeping the money from the transaction.

Fightingback
Recognizingfraudattempts
Before we can stop a fraud attempt, we must be able to
recognize it before we process a transaction.
There are some indicators which should be used to detect
frauds attempts, with multiple occurring at the same time
indicating a higher chance of fraud:

The billing country and the IP country (via geolocation) do


not match. Advanced attackers will be using a proxy
though, more on IPs and proxies later.

Usage of a proxy to disguise location and attempt to avoid


the previous indicator.

IP country (via geolocation) is from a high-risk country.

Usage of a free Email service for the provided Email (if


you have an Email field in your payment form). Email
accounts with private domain names are less likely to be
used in a fraud attempt. Again, if the free Email service is
from a high risk country, it increases our suspicion of
fraud.

An unusually large purchase. While by itself is not a real


indicator, combined with any other indicator raises the
chance of fraud, in addition to the risk of losing more value
(in the case of physical goods).

High velocity of purchases by the same person multiple


purchases in rapid succession over a short period of time

are a good indication of a fraud in progress. The various


ways to track a person between transactions are
discussed below.
I will now suggest an actual process for getting the
information needed for those indicators. You can skip any
of the steps, but the more indicators you have the better
you can assess the risk of fraud.
1. Check IP
Using the client machine IP, we can attempt to determine
the location of the person attempting the transaction via
geolocation. In addition to the standard IP headers,
proxies might send the actual IP through a long list of
alternative headers. See this StackOverflow question for
such a list and mock code (in PHP).
Detecting and using a proxy alternative IP header is
important for a couple of reasons

First, we have the actual IP to use in the next step


geolocation.

Second, using a proxy by itself is a strong indicator of


fraud. While not all proxy users are fraudulent users, fraud
attempts are much more likely to use a proxy than your
average user.
2. Fetching the client address via Geolocation
A geolocation service will receive an IP and send back an
approximate address that corresponds to it. You can use a
geolocation service via an API or via an IP database on
your server. A good free database can be obtained from
Maxmind, as well as a more accurate one and an API for a
small cost.

Once we have the client IP from the previous step, we use


our preferred method to fetch his/hers location through our
geolocation service.
3. Compare client address to billing address
The rule of thumb is simple the farther away the client
current location is from his billing address, the higher
chance were dealing with a fraud transaction. The chance
of fraud increases even more when the location is
confirmed from a set of high-risk countries (mentioned
above in the list of indicators).
The billing address should be collected on the payment
form for credit-card transactions, or via
GetExpressCheckoutDetails API operation for Paypal
transactions, before confirming the transaction (if you use
the Buy Now buttons instead of the API, youre out of
luck. Consider switching to the API we have a great
Paypal API component for PHP that makes using it very
simple).
Of course, an address mismatch by itself is no
confirmation of fraud. People travel all the time to different
countries and use their credit-cards to make payments
online. We should use this information with the other
indicators to assess the risk of fraud.
4. Check Email address
Note: this step is only applicable if you collect an Email
address in your payment form, or use the Paypal API
which provides it in the billing details.
As mentioned before, free Email services are much more

likely to be used in a transaction and especially if the


Email service is a fringe, lesser known service. There is
quite a comprehensive list over at Yahoo, and you should
add the domains of each to the check you run on the
provided Email address.
If the Email address is from a free service, we should take
it into account as another indicator with the others covered
so far.
5. Consider size of transaction
Larger transactions are more likely to be fraud than
smaller transactions. When we have hit several indicators
already, the size of the transaction should be used to
downgrade or upgrade the chance of possible fraud.
In addition, calculate the possible losses according to the
size of the transaction (especially if dealing with physical
goods), and use it to lower or raise the bar for which a
transaction might be flagged as a possible fraud.
6. Review bank credit-card checks (credit-card
transactions only)
This step does not apply to Paypal transactions as they
run their own fraud detection system and do not provide
such information before completing the transaction.
Most payment gateways will allow you to receive the
results of the checks the bank runs on a credit card before
completing a transaction.
For Stripe users - If you use Stripe, like us, you might not
realize they do provide this option, though not directly. You

can get the results of the bank credit-card checks by


creating a customer with the payment token before
actually processing the transaction, and then deleting the
customer once the transaction has been processed.
Ideally, they would have provided this information when
the token is created, but currently they do not.
The fields banks can validate aside from the actual card
number include the Zipcode, CVC security code (found on
the back of the card), street address and expiry date.
Different banks run different checks, and you might decide
to reject a specific card on the grounds that his bank does
not provide enough security information (such as not
validating the CVC or expiry date).
I personally consider CVC, Zipcode and expiry date
mismatches as showstoppers. Those are details that
cannot be incorrect, while the address field is a bit harder
to validate (everyone writes addresses a bit differently,
and its also hard to correctly write down foreign street
names in English).
Making a mistake on any of those does not necessarily
indicate fraud, but should stop the transaction. Making
multiple mistakes in rapid succession though is a good
indication of a fraud attempt.
7. Check the logs
I will cover the actual logging of the transaction in the next
step, but before we get there in the actual process, we
want to check our logs for suspicious behavior. Suspicious
behavior might include:

Multiple transactions in a very short time by the same


person

Multiple failures over a longer time period by the same


person

Whether the person was previously flagged as fraud (by IP


or session ID see next step)
The amount of transactions and time frame that should
trigger a fraud alert is up to you. You can attempt to gather
that information by reviewing the logs after several frauds
have taken place, or by attempting to guesstimate
numbers that make sense to you.
8a. Suspected fraud log the attempt and deny the
transaction
With all the data we have accumulated thus far, we have
decided we have a possible fraud in progress. At this
point, we will show a message to the user, and log the
transaction attempt for future reference (and for step 7).
Details we want to store:

Client IP

Proxy IP (if we found one)

Country (and city optionally)

Client user agent

Client session ID (if you are using sessions which you


should, for this purpose at least)

Transaction attempt date/time (timestamp)

Other identifying details relevant to your service (such as


user identifier if you have it)

Transaction status (failed in this case)


Why do we store both IP and session ID? while both can
be changed between transaction attempts, they can be

considered as failsafes for each other. Our attacker might


switch to another proxy but still use the same browser for
example. It doesnt hurt to have as many data points as
possible.
The message we will show the user at this point depends
on your philosophy I suggest not mentioning fraud as
the reason as you might scare away potential clients as
well as alert the attackers that theyve been caught. You
can say the card was rejected by the bank (in the case of
a credit card transaction), or that Paypal has rejected the
payment. I leave the actual wording up to you.
Optionally, you might choose to manually review
suspected transactions. In this case you should show a
message indicating the transaction in under review and
the time-frame for completion. If you do choose to
manually review transactions, remember to save all the
details youll need to complete it later, such as payment
tokens or even credit-card details if you know what youre
doing (if youre not PCI certified, Id highly recommend
against it).
In extreme cases (close to 100% certainty of fraud), we
might go as far as block the payment form for the IP /
session ID of the attacker, and at this point we will show a
message mentioning suspicious behavior so that legit
clients can contact us and notify us that they are not in
fact attempting fraud (this has happened for us once at
Binpress, and the verification process wasnt that simple).
8b. Log and process the transaction
If we made it this far and have not reached our threshold
for determining a fraud is in progress, we will try to
process the transaction. Regardless of whether it was

successful or not (rejected by the bank or the payment


gateway), we will store it in our log for future reference
(and for detecting a high volume of purchases by the
same person).

ThecaseofPaypal
Weve mentioned one attack pattern that we havent fully
addressed yet usage of an hijacked Paypal account to
make a payment.
While the same indicators apply, we have an additional
option to confirm legit account ownership by verifying
the Paypal account Email address.
The Email address (and billing country used for one of the
indicators), can be obtained before confirming the
purchase via the GetExpressCheckoutDetails API
operation (assuming you use the API. If you use the Buy
Now buttons, you are out of luck).
This means implementing a process similar to the
following:

On the Paypal confirmation page (after user has


confirmed payment in their Paypal account), we check for
any of the previous indicators by getting the account
details with the GetExpressCheckoutDetails API method
and examining the user IP.

If we suspect the account might be compromised, or the


purchase is large enough to require more caution, we
send a confirmation Email to the account Email address
with a unique identifier (usually in a link back to our site).
We save the identifier and Paypal payment details in our
database or in the session.

If the user opens the confirmation Email (meaning he has


access to the account Email) and returns to our site with
the identifier, we confirm the transaction and finish
processing the payment.
Obviously, if the attacker has control of the account Email
as well, he can easily bypass this method as well. If the
indicators are very strong, we might consider holding such
transactions for manual approval.
Note that you cannot change a Paypal account primary
Email without entering one of the complete payment
details (such as a credit-card or bank account numbers).
Any change or addition of Email accounts to a Paypal
account will notify the original Email account as well.
Something worth mentioning is that you cannot distinguish
payments with a Paypal account from payments using a
credit-card through the information returned by the API.
This is a problem in the sense that there is no point in
sending a confirmation Email to someone who used a
credit-card to pay, as the Email given is the one he
entered at payment (meaning he would likely have access
to it).
The only indicator between a Paypal account payment
and a credit-card payment is the PAYERSTATUS
parameter in the billing details returned by
the GetExpressCheckoutDetails API method. A Verified
status indicates that is a Paypal account payment, while
an unverified status can be either. For this reason, we
only send the verification Email to accounts that are
verified, while we use more caution with unverified
accounts.
You might even consider rejecting unverified accounts
outright, just keep in mind that you wont be able to

receive credit-card payments through Paypal if you do.

Buyersremorse
The trickiest type of fraud to handle. If possible, always try
to obtain proof that the user has made the transaction
himself. If you ship physical goods, obtain proof of
successful shipment.
For digital goods you can use try to ask for an
authorization Email or a declaration of purchase (using
digital signature services). Naturally, this process it not
appropriate for most websites, and in that case you will
most likely have to swallow the fraud as a loss.
Another factor is the originating country (if you serve an
international audience). High risk countries are more likely
to fall to this kind of fraud as well, which is one of the
reasons many services do not accept payments from such
countries.

Frauddetectionservices
If all of what Ive described so far sounds like a pain, its
because it is. If possible, I would suggest passing this
information to a proven fraud detection service, and rely
on their experience and expertise to increase your fraud
prevention success.
A fraud detection service might be provided by your
payment gateway. If not, or if you are not satisfied with it, I
personally recommend the Maxmind Minfraud service.
You might have noticed Ive mentioned 2 Maxmind
services here and its not by accident (and no, its not
because I was paid to promote them ).

The Minfraud service receives the information we


collected thus far and provides a risk score and other data
for our assessment. They use their own geolocation
service to determine the location of the client (we pass
them IP addresses we found), and in addition, they have a
database of known proxy IPs that can be used to
determine when a proxy is being used and how dangerous
it is (how prone it is to be used in fraud attempts).
They use that data to compare with historical data they
collected on online fraud to calculate the risk score
which is basically the chance the transaction is a fraud
attempt (in percentage points).
The reason Im advocating Maxmind so much, is that
since adding Minfraud to to our payment process, we have
not had one fraud slip through their checks (and we had
quite a few attempts). We use it in a combination with
logging and the bank security checks review to very good
effect.

Bagitandtagit
So there you have it a basic guide to knowing, detecting
and preventing the most common types of online fraud. If
you feel I missed something or have a question regarding
something I wrote, feel free to add your thoughts in the
comments.

You might also like