A small Stripe fraud story
falkus.co
falkus.co
The hit is usually doubly painful for us as we not only lose the money, and get the 15$ Stripe dispute fee, but we’re still on the hook for the restaurant’s food and driver’s tip and need to pay that out of pocket, and we also lose valuable time from our drivers. So all in all, a 50$ fraud might cost us 80$.
The signs are always obvious. Always ~70$ orders. Asking for the food to be delivered to a person across the street. Obviously fraudulent names and emails. Postal codes from elsewhere in the province. Orders from only certain restaurants. The problem, we always catch this too late through manual reviews. The restaurant usually has the food made before we find out.
Despite mitigations, blocking blocks of addresses (digital and physical), Radar, etc. it’s still trivial to get around and make fraudulent orders if you’re able to constantly acquire a fresh supply of new cards. We can probably build more sophisticated detection mechanisms, but we haven’t gotten there yet.
We’ve resorted to just cancelling the order quietly once we find out, without informing the fraudster. When they invariably call an hour later inquiring about their delivery (with a voice totally not matching the name), we either tell them we’re sending cops or cuss them out loudly. The silver lining is that it’s fun to witness their reactions on the phone when they realize they’ve been caught.
The banks and police are no help. There are obvious fraud patterns (we’ve physically seen the crooks and know where they live) and we have compelling evidence we can provide, but they won’t do anything. Understandably, they’re fighting the problem at a much greater scale and probably don’t have time for small peanut cases like ours, but it’s still frustrating nonetheless.
Here’s a recent example: They investigated guys who robbed Verizon stores, which led them to guys who bought phones from those guys, and wholesalers who then bought phones from those middlemen and exported the stolen phones to Hong Kong and Dubai. The value of the fraudulently obtained or stolen phones in the above case is about 100 million dollars and has resulted in various leads ranging from rogue carrier employees unlocking phones to drug cartels using cash to buy phones as part of a trade based money laundering scheme (see also https://storage.courtlistener.com/recap/gov.uscourts.cacd.85...)
And like come on, cops are the only thing that allow me to wake up in the morning, stedda getting gutted in my sleep. Specific reason I had to dodge getting whacked after handing a racketeer to police ten years ago, my life depended on police retaliating for my murder. We had a hostage deep in the joint hopeless legal case, got caught on the scene of the crime because of my defiance. He would have paid for my getting whacked, human shield.[1] Counterproductive whack, when California gets pissed which is never but this was never so when they're pissed, they're perfect. Arrested the racketeer perfectly, like the wheel of the police car wheel rubbed against the sole of his shoe crossing the street, four guys--cavalry arrived--pinning him against the wall with no possibility of accusing them of police brutality. He angled his back into it so they'd hurt him--bitchvictim racketeer--they knew the counter move. He was stealing from the police, rackets mean Starbucks would have to cook the books for that location, that meant no profits, no profits no taxes. Protection money, well there can only be one protector. Taxes, the protection money that doesn't cost twice as much every time you pay.
And they protected me, again, human shield. Tragic fucking story twitching up his allies. Not even perpetual solitary confinement, or just as simple as competition in maximum security, which I'm not sure he got, even medium security, murderers bigger than him in competing gangs, and like no respect for anybody ever, treating him like shit (I've been top dog when falsely incarcerated, I know the cage)...plus prison in California is segregated, so it's not like he can carry on the race war he declared on Daniel Cussen very effectively, can't gang up on whites so much anymore. And like how many allies does he need?
Well so I need an ally in some sense, the police. But taxes mean they're not truly allies, they're protectors. Detectives on the case. It's not that confusing why I paid taxes, it was not unmotivated. Made sure not to pay the minimum, that sucks, pay what you can, don't pay when you can't but pay when you can. Dude State of California is the best, the political culture in California is disgusting the rent the private university deans--but--the State of California has pulled out the impossible with minimal budget. I can make that budget less minimal. So it wasn't much money--$20 a work week at minimum wage--but now I can talk shit about billionaires like Bezos, especially of their charity, which they should shut the fuck up about. You cannot brag about charity.
Taxes are not charity, so you can talk about that, I've talked to Marxists who were very surprised but agreed taxes aren't charity, taxes can be public. Fuck tax deductible charity. Then, you can leave charity totally to the imagination, or revealed long after death. It only cost me $80--half federal, half state, and twenty bucks per week each just off the top of my head--to make Californian billionaires look niggardly. 100% marginal tax rate. And it counts extra because I had so little, Book of Matthew says so. Not like I miss those $80, I dream of all the ways the State could have spent them, on an orphan for instance, an extra budget to treat him with better food on his birthday. Pay less interest on municipal debt. On gas for the squad car so it can get to Kearney and Bush in the time I bought them, a gas guzzler with crazy horsepower comfy seats and a watertight cage in the back. In a top district attorney that can shut police brutality accusations the fuck up. On a judge or especially a juror's diet (like wage), pay those jurors double minimum wage at least, so they don't think of money while they think about guilt. Just about no problem no matter what they spent it on in practice. Some expenditures hurt--fluorine in water especially--but rather than tell them what to spend on, I trust them above myself to come up with ideas.
And I can declare it with no shame--Christ paid 100% taxes, after all, he never gave charity, he alone healed schizophrenics outright but never gave them money. Caesar he did, in the attitude of sossegation (coining the term, based on sosegado in Spanish, beyond serenity, Christianity). And it's as easy as pulling a fish out of the water with a gold coin in his mouth. Dude algorithms are easy, I'm going to set to work to doubling a speedup after posting this. Doubling is easy, but doubling has a cost and if you double nothing you can never pay that cost. And charities just don't work, I can give a beggar money directly instead.
Sierra says not to do this, Sierra says give to Sierra, yeah why would that be, no, these days I cut out the middleman. Give those beggars money for whatever the fuck they want, even crack if that's what they want, the State does that, yeah it's terrible but I'm not the one sitting on the sidewalk doing the work of begging, they are they choose. Tell them about better drugs, upgrade the crack to a stimulant.
I saw one of my friends with all this food and he offered me some and I accepted, it made me so happy to see him eating food, he didn't have to but he did, and then he showed me how much of the gift I gave him he had left over for the following days. Responsibility is partly about the amount of the gift, big payouts are sobering. And just like people helped me out when I was fucked. Doctor Derek Dunham. Doctor Anne Green. 911, 5150, beautiful numbers, my salvation from Mortal Kombat on May 12, 2012.
I couldn't have tanked the whole gangsters infinitely. Racketeer was 5'8", hitman was 5'11", then assassins both 6'4" for sure, then they get taller and taller and heavier and heavier and more and more and no longer weaponless, sumo gangster then I'm plain fucked, double my weight can't do it. I asked that when I trained, what's the weight limit, double my weight? "No." Triple? "No." Sumo? "Sumos are dangerous."
[1] Paid any way he could hey tooth fairy might leave a quarter under his pillow, that's money. He'll pay for all of it. Got genetic sequence done too, he didn't talk but he sucked. Threatened to murder me, and made a team effort, RICO act field day. Pointing at me for seven minutes? Yeah whack incoming, 911 into 5150: "I think I'm being followed" "oh you're feeling paranoid" "yeah" "we'll send police to come get you to a place you'll be safe, 5150, you just stay there".
Larger agencies like the FBI have more intake points, but don’t seem to reliably route to local police.
Are they? Seriously. The FBI maybe is. But local police almost certainly are not.
That being said, if there was a way we could signal to all the would-be-offenders that we took prior cases to court, that could be quite worthwhile.
But you are right, they might claim inability to pay.
* if the postal code is a million miles away, flag it for manual review;
* check the IP address (and its ASN) and start identifying ones that are used commonly in chargebacks; if they're using a mobile device with a mobile network it's trickier, same if they're using proxies (though residential are harder to come by now that vip72 is no longer around)
* check if an email address actually exists and isn't just a carder's fresh email — like you said it's pretty obvious;
* don't deliver to person across the street;
* do some sort of phone verification/confirmation (and don't trust VOIP-type phones) (though this is still beatable, it's at least another cost to the carder).
Lastly, when you have a suspect order, don't tell them that you've cancelled the order due to fraud, or that you've found out: tell them that you're having trouble processing the order with the confirming bank and that you need them to enter another card. They will try again, burn some of their own money, and you'll have everything ready to go.
Querying your database and looking at patterns is certain to be helpful. Just a few joins and you can find a lot.
Happy to talk more offline to help you identify this better. Email in profile.
I feel like this is probably crossing over the line balancing an acceptable amount of inconvenience to genuine customers vs. the amount of fraud that is prevented.
Certainly it's fine to flag such a transaction for review, but it's not at all unusual to order food from a restaurant over the street. For example, when it's just me and a sleeping baby at home, but I really want to eat the food from the restaurant over the street.
Basically the fraudster is asking to deliver to a location other than where they actually live, because they don’t want to be traceable. They don’t want the delivery person to ring the door, because then the fraudster might lose out on the food.
For example, we lose a lot of potential clients due to them being turned off by the phone verification, though we rationalize that by saying that the support and operational costs are a lot lower this way as the driver can get in touch with the clients should there be any issues.
I think the next steps as you outlined are to build additional flows for fraudulent users and regularly verifying some heuristics on our data. We’ve haven’t gotten there yet due to it not being that pressing, but it’s clear we’ll need to do so as we keep gaining traction.
I’ll definitely keep your contact in hand when we visit this issue further!
* disallow registration with disposable email addresses (increases the cost for fraudsters). See: https://github.com/disposable/disposable
* disallow or flag transactions depending on ip-rating services. See: https://iphub.info/api (you could cache sketchy addresses to prevent exceeding the requests/day limit)
The time my manager accidentally ordered food from a place we could see out the window was amazing. I’d have been sad if that was blocked.
NEVER do that. You’ve got a contract with the customer, you have to either fulfill that or properly explain why you’re breaking the contract.
I’ve had a company break a contract with me (as it later turned out, because I hit one of their fraud measurements) and it took quite an annoying legal battle to force them to accept me as customer (but they had to, and I got almost 2 years of free service out of the company).
If you follow this advice, expect that at some point a customer will be accidentally affected, and some of them will sue you. And you’ll lose.
A commonly known example is the person who auctioned off farm equipment on ebay, the customer bought a tractor for 1€, and the seller tried to void the contract and refund the customer.
The obvious court decision was that the contract had to be fulfilled, the tractor had to be delivered.
There's very few exceptions in the law surrounding that:
https://www.gesetze-im-internet.de/englisch_bgb/englisch_bgb...
I'm sure in other countries laws it's similar.
Don't do this. Just give an automated message that you've canceled the order due to being unable to process their payment, without elaborating on what was wrong with the payment. If they call, give them the same information and nothing more.
Every piece of additional data you give them about how your anti-fraud system works helps them to evade it. Also, as you grow, speaking to them on the phone will become a larger and larger risk as some fraudsters will be very skilled at convincing your customer service people that they are legit.
> Every piece of additional data you give them
Yes, we shouldn’t give them additional data
> Give an automated message
??
An automated message arrives every time, one time. For this specific type of fraud where they are trying out many cards to figure out which works, getting an automated message is perfect.
Leaving the fraudster in the dark - excellent. Forcing the fraudster to call if they want more information - excellent. Both of these increase the time investment from the fraudster. They need to spend more time per card.
Cussing - doesn’t make a difference either way from an information perspective.
It's literally less information versus directly letting them know. One message lets them know you know, and the other doesn't.
> Forcing the fraudster to call if they want more information - excellent.
But there's something else you're not taking into account, which is innocent people who trigger your fraud detection.
>Cussing - doesn’t make a difference either way from an information perspective.
Well it certainly lets the fraudster know you know. A legitimate customer receiving that kind of abuse would be pretty unusual, don't you think?
You’ve mistaken me for the average. I’ve worked in Integrity for a FAANG company and in FinCrime for a bank. I have a very good idea of how to mask information from bad people automating things. That’s literally all I’ve done for more than half a decade.
Save your condescension for someone else.
> I don't really see a point in continuing this conversation.
The only worthwhile thing you've said.
Phone number verification is the first like of defense. The delivery person might need to call you anyway, so it's an okay compromise to verify the phone number. Only accepting phone numbers from the sake country as you deliver is an added defense, but makes it somewhat inconvenient for travelers without local phone numbers. I'd ease this requirement for neighboring countries (accept US or CA numbers within those two, any EU number within the EU, Singapore+Malaysia, Nepal+India, etc).
Second, adding a card number requires verification too. Charge a small amount, and flag to the payment provider to require secondary authentication the card owner has with the bank. Any serious card owner should have Visa 3D Secure, Mastercard Code, or something similar setup).
This will leave legitimate gift senders (sending muffins to a friend in birthday while I'm in a different country) and travelers, but you'd make that lost revenue by cutting losses for fraud.
To be fair, the card fraud is not driving the business into the ground per se, just more annoying when it happens :) solving the problem is more of an opportunity cost thing for us
Not to derail from the discussion about Stripe, but having a local payment processor helps a lot. In countries with foreign reserve woes (Sri Lanka and Turkey for example), Central Banks impose additional restrictions when paying foreign entities with cards. This can be in stamp fees (about 2.5% of the amount) or a daily/weekly cap on the amount.
For example, hardly anyone uses their credit cards with Uber in Sri Lanka because of this, and a local startup takes many times more orders because they partner with a local payment processor and charge the card as a local entity, sometimes with lower fees too.
The suggestion for a local payment processor is a good one. We have another processing entity here in Canada called Interac whose fees are considerably cheaper, though consumers don’t reap the benefits of credit since it’s debit.
I’ve also read about Uber’s efforts accepting cash payments which I found to be very interesting: https://www.uber.com/en-EE/blog/india-growth-cash-payments/
To be fair amount the margin, the drivers are paid for completing 20, 50, 100, ... deliveries, which is the bigger portion of their income.
In Indonesia, Grab and Gojek both charge 20-30%, if I'm not mistaken. In Vietnam, Grab, Gojek, and Baemin all charge about the same too. I have lived in Indonesia and Vietnam, and have seen the very same shop marking up the delivery fee into the food. I imagine this is a common practice in Asia at least.
Alright, cool, a consultant. And then…
> Sri Lanka (where I currently live and run a bakery business),
And suddenly a bakery business.
I wish my life one day would be as interesting as yours. HNers are quite interesting.
On topic, FoodPanda is another popular one I’ve seen in Asia. And yeah, the markup for all of them seems to be close to your stated range. Though, it seems that Grab’s delivery fee changes depending on the number of available drivers (motorcyclists?) unlike their competitors like FoodPanda which is static from my experience.
Things tend to be cheap in Sri Lanka, and rent isn't really that expensive, so it was not that difficult to start the business.
The bakery is mostly for the excitement, although it is turning profit so I'm not complaining. I'm only investing and and involved in a small level, with a chef and a manager I hired. But it was a wonderful experience arranging stuff from ovens and mixers to signboards and corrugated boxes, with all minor details in between.
Things tend to be cheap in Sri Lanka, and rent isn't really that expensive, so it was not that difficult to start the business.
Stripe's Radar is all well and good, but they have no skin in the game. If they're right or wrong, you're on the hook.
Services like SIGNIFYD apply their own fraud logic. If a transaction is approved and is later disputed, you are refunded the value of the order and the chargeback costs.
Not associated with them, but have been using them for several years and hundreds of thousands of transactions; our fraud problems are non existent.
It's not wrong. Someone used a leaked API key to do card testing. That explains why someone might be interested in the API key. However, the bigger part of the story is that Laravel or whatever framework they used has a dangerous footgun that can easily lead to exposing secrets.
> The environment configured on the live site was actually set to production, but the configuration also has APP_DEBUG=true set which is why a 500 server error response was giving such neat and useful output.
It should be easy to add additional safeguards / warnings to prevent this combination from being set.
It's still a footgun. It's pretty clear that this shouldn't be done, so why allow it this easily?
In prod it should emit a log message saying "you cannot do that. if you really, need to follow these steps: <something cumbersome like placing a file somewhere with some dedicated end date for debug mode, or scoping rules>"
A secondary problem is that ultimately those taking payments end up having to either track you, or side with someone that does, as a way to try to detect suspicious activity. Whether it's Stripe directly, or Google via reCaptcha, someone is going to have to be peering into the metadata of your transaction to try to figure out if it's really you that is calling, or it's a fraudster. And when the store gives that traffic to Google, they aren't just going to use it to make sure you are who you say you are.
It's really unfortunate that the card issuers are the ones that can fix the problem, while in practice, it's companies further down the line that are paying for this in fraud and fraud detection spend.
Every time I make a big purchase locally to a local merchant I have to use an OTP from my bank.
American companies never want to do it. Apple wanted me to send them bank statements to verify I was the card owner. I asked their fraud team to just use SecureCode and they had no idea what I was talking about.
Classic collective action problem. I'd guess the feds will mandate it at some point in the future, like how it took a decade for EMV to be mandatory in the US.
https://www.practicalecommerce.com/Are-Verified-by-Visa-and-...
Visa / MC require you to keep your fraud rates under 1-2% anyway, so 12% is an enormous hit to only slightly improve your fraud rates.
"Furthermore, Visa observed that independently of the SCA method used (SMS, Password, Bank credentials, etc.) when customer intervention is requested the abandonment rate is between three to five times higher than when authentication happens frictionless via RBA."
https://www.eba.europa.eu/node/81948/submission/532
EDIT: While I'd prefer to take Visa's own numbers, "Global Banking & Finance Review" published statistics in May 2021 claiming decrease in conversions of 25% - 50% across Europe after the introduction of the EU Payment Services Directive 2 requiring Strong Customer Authentication.
https://www.globalbankingandfinance.com/the-real-impact-of-p...
[I wish Visa Europe / Mastercard published their own data somewhere easy to find, instead of wading through 3rd party data from companies with an agenda. Maybe it's out there and I haven't found it.]
"Moreover, after only 3 months of 3DS flow implementation, the European grand total of authentication rate improved from 61.8% to 74.5%, with the UK being an absolute leader with almost 90% authentication rate in 3DS flow with Mastercard. Frictionless flow (3DS exemption) was the main reason for this high authentication rate. Authenticated frictionless transactions (exempt of SCA) accounted for almost 30% of authenticated transaction (21.4% pre-3DS), the reason was yet again the real-time efficient TRA. The UK was the leader again with 61.4% exempt transactions with Mastercard, along with high exemption rates in Spain, Greece and The Czech Republic. Axerve, in turn, reported that the authentication conversion rate was 76.22% after 3DS protocols became obligatory."
https://www.axerve.com/en/learn/insights/transaction-risk-an...
Unfortunately, that's an issue with services like Sift if you need to comply with laws like GDPR. Anybody nows if there's a GDPR-compliant alternative?
unfortunately the only way to stop this seems to be to increase friction and suffer the conversion rates.
Most of the European and Asian countries (apart from China) are far more advanced with payment cards. Many not only have their own networks with 0-1% commission, compared to 2-4% on Master/Visa/Amex, but also have long required 2FA for online payments.
They might be less tech savvy users, in that they will be taken as a surprise if a car rental company posted a temporary authorization or if someone charged your new card after you renewed it (Stripe can do it), but SMS/email 2FA is quite frictionless nowadays.
US was in fact one of the last countries to commonly issue EMV (chip) cards.
Thanks!
I heard about this happening yet again too last month - August seems to have been the month of Stripe key leaks.
But the best way to prevent this is to absolutely make sure secret keys are kept secret! We try to scour for leaks in the wild—and notify the owner directly—but can’t see everything.
It seems odd this is even possible, does stripe not allow you to register an ip whitelist for token generation etc so that at least part of the payment process must go through your site?
It seems like stripe rate limiting is just on the api level, so you would need to implement your own ip based rate limiter on you site, if you could force part of the process to go through it.
I still genuinely don't understand why such a basic thing as ip restriction is not part of the security settings in stripe. I keep looking for it thinking I must be missing it. On the user's site, it could be as simple as a fail2ban rule to deal with most of this. And no doubt he is not the only one to have done such a thing, given the number of libraries and frameworks people throw on their sites, all with their own layers of configuration.
We’ve also disabled use of pre-paid cards because we often see subscriptions with the sole purpose of bypassing trial limitations (e.g api limit) to abuse our services.
Another fraudulent scheme that’s concerning for Stripe users is someone doing chargeback after a year of subscription - banks always side with the card user (even with login logs) and Stripe dings you $15 per chargeback - unless you signed up for Chargeback Protection.
Is pasting your card info wrong? My card info lives in my password manager so yeah I paste it in.
In our case the card was issued by a Saudi Arabia bank but the user pasted it from Morocco.
Are you expecting your customers to literally hand-type card numbers into a website every time?
When a charge is denied or flagged for review you can see signals used to score the risk.
If you sell B2B in Morocco it wouldn't be unusual at all for some businesses to have parent companies or banking relationships in SA. Maybe in your context the countries individually are already a signal, but the combination of them is not that crazy.
Someone enters a credit card and a bad CVV, Stripe sends it to the bank for validation, it fails, but the bank approves the charge anyway. Now you have an approved charge with a bad CVV. The bank punted the problem back down to Stripe, and Stripe punts it to you to figure out.
It is why I also cringe when people chargeback before they ask for refunds. The system is stacked against the retailer.
I think it only makes sense for certain types of business. For retail at <$200-$400 AOV, it didn’t make sense. Maybe for <$100 it might make sense to deter testers, and maybe for much higher values it might due to the risk.
So I'm guessing that Radar's price was set with this in mind, you ran the regression to set a price to ensure revenue does not decrease by having better fraud detection. Hence the super expensive price. If this wasn't the case, Radar probably would be free.
Probably creates a really bizarre incentive. You don't want to deal with obvious scams that hurt processing reputation, but you probably also want to make your built in fraud detection just crappy enough to ensure you capitalize on that revenue.
On the dispute fee, banks charge varying amounts (they employ dispute investigators to read evidence, so it costs them to process). Some charge $10. Some charge $20. The average is $15, so we pass that $15 onto the Stripe user. (That way when accounting, the user doesn't have to factor in different fee amounts per bank—they only need to count the number of disputes, which is much easier.) We flex the average based on the country too—e.g., AU banks charge more, so the dispute fee is $20.
If a business wins the dispute, though, we refund the fee at our expense—the banks do not—because we feel it's the right thing to do.
> Sites that aren’t static either need to be retired or kept up to date.
In my experience, not just sites. I’ve released over 20 apps, but most have been retired. I’ve also learned to “churn” the apps I keep up. I once received an offer to buy one of my apps. It was a simple app that hadn’t been changed or updated in a couple of years (not necessary), so I suspect the hacker assumed it was moribund (it was not). They would buy the app, repackage it, with an extra “gift,” then use Apple’s update service to infect previous users. I guess they knew how to sneak the trojan past App Review.
I ignored the request. I’ve learned it’s not a good idea to “poke the bear.” I watched a friend lose a large phpBB site, because he attacked spammers (and they retaliated).
Scammers/spammers/fraudsters are getting really clever, these days, and they have learned to leverage sloppy coders.