This is a short story about how I caught hackers timing their attacks around my daily routine.
A couple of weeks ago, in the middle of the night, I got alerts on my phone that various metrics were going haywire.
The only thing I noticed was a huge spike in sign-ups. This coincided with one of my articles being on the front page of Hacker News, so I didn't think much of it.
It had spiked for a few hours and flattened out just before I started troubleshooting, so I went back to sleep.
When I woke up the next morning, a few thousand more accounts had appeared.
I thought this was a bit suspicious, but ... even if someone was being naughty, they seemed to have given up.
Nothing else was out of the ordinary that day. I even decided to stay up later that night to see if the pattern would repeat. Nothing.
As a small precaution, I activated CAPTCHA to slow down the sign-ups and went back to sleep.
The next morning, you guessed it... same pattern.
This time, I decided to do a deep dive into the data.
What I found was that the hackers were...
- creating thousands of accounts
- adding a valid payment method to each account
- running a single very expensive LLM call (2-3 USD)
This would let the first request go through, then trigger a charge to their payment method. The payment method gets rejected, but the request has already been processed.
The reason the first request goes through is that we deposit a little bit of money into the account when it's created. A nominal amount that's enough to play with the API. However, if a payment method is added, we allow people to go into overdraft, which is why their expensive LLM call goes through.
Anyway, using this method, they would get away with about a thousand dollars' worth of credits every night, which kept them interested in the service.
But what caught my attention wasn't the money – it was the timing. The attacks coincided with my sleep cycle.
At this point, I still thought of it as unlucky timing, but even then something just didn't sit right with me.
Coincidentally, that day I decided to take a break and disconnect from my computer early. And lo and behold, just 30 minutes after I shut down my computer, I got the first notification.
I logged in to check, and it stopped.
Went to play some games and ... 30 minutes later, I got the second notification.
That's when it clicked – the timing of the attacks wasn't random. They were checking my Discord status to see if I was online.
Sure enough, I confirmed this by setting myself as offline on Discord, and the attacks popped right back up.
Over the next few days, I used this insight to mess with the hackers and to use them as my personal pen testers.
I didn't want to remove free credits for everyone, so I began experimenting with different ways to deter future attackers.
I would make a change, then go 'offline'. I'd watch them troubleshoot their automations until they figured out a workaround. Then I'd go back 'online'. The attacks would resume, and the cycle would repeat.
I mostly forgot about the entire incident until they came back to try their luck again the following week. But despite a few nights of alerts about tripwires getting triggered, they never managed to get more than the few cents we deposited into new accounts – not enough of an incentive to keep trying.
In the end, it was the cat-and-mouse game that made the whole experience worth it. I got free pen testing; they got a few dollars.
Card testing vulnerability
I wasn't surprised about the overdraft feature being abused. This was something we were aware of and treated as a conscious trade-off between convenience and risk of abuse.
The bigger issue was that this made me realize that a malicious actor could abuse our system for card testing. That's a widespread problem and one that will get your Stripe account flagged. When researching this problem, I didn't find many effective solutions, so I wanted to dedicate part of this blog post to sharing what I learned.
Here's what I tried and how it held up:
| Method | Effectiveness |
|---|---|
| Device fingerprinting | Ineffective. Fingerprints are great for detecting legitimate returning users (e.g. to bypass CAPTCHA), but because they are easy to fake, they are not effective at detecting malicious actors. |
| IP address blocking | Ineffective. Residential proxies are cheap and easy to get. |
| CAPTCHA | Mild deterrent. Ineffective. Many existing solutions to bypass CAPTCHA. |
| OTP | Mild deterrent. Ineffective. Many existing solutions to bypass OTP. |
| JA4 | Somewhat effective. JA4 is a TLS fingerprinting method that identifies clients based on how they negotiate TLS connections. Of all data points that we collect, JA4 is the most stable identifier. |
| ALTCHA | Somewhat effective. ALTCHA is a proof-of-work challenge that requires the client to solve a computational puzzle before submitting a request. When combined with prior methods, can slow down the attacks enough to deter the attacker. |
| Rate limiting | Somewhat effective. Slows down the attacks, but may hurt legitimate users. |
At the end of the day, each method is individually bypassable – the game is making the combination expensive enough that the attacker moves on.
Oh, and set your Discord status to offline.
Top comments (1)
The Bio-Digital Feedback Loop: When Your Sleep Cycle Becomes a Signal
This is a masterclass in seeing the "invisible" data streams that connect our physical lives to our digital systems. It’s easy to think of security as a wall of code, but you’ve highlighted how it’s actually a living interaction between two opposing intents.
The Human-in-the-Loop Vulnerability
What strikes me is how the attackers didn't just find a hole in your logic (the overdraft feature); they mapped the rhythm of the defender. This reminds me of how complex systems often fail not at their strongest points, but at the "seams" where different data flows meet—in this case, your Discord presence acting as a proxy for your system’s active defense. They weren't just hacking your API; they were hacking your circadian rhythm.
Seeing the Systemic Flow
From a broader perspective, every security measure you listed—JA4, ALTCHA, Rate Limiting—isn't just a barrier. It’s a way to increase the computational or financial friction of the attacker's stream.
By turning the attackers into "accidental pen testers," you essentially inverted the flow.
Instead of them draining your resources, you used their energy to identify the specific "density" of friction needed to make your system unprofitable for them.
The Cost of Convenience
The "overdraft" feature is a perfect example of a tension-point in system design. You optimized for a "frictionless" user experience for legitimate people, which inherently created a high-velocity flow for malicious actors. It’s a reminder that in any open architecture, the "ease of entry" for a friend is almost always an "ease of exploit" for a foe.
A Reflective Takeaway
Perhaps the most potent "defense" here wasn't a technical patch, but your shift in perspective—moving from being a reactive responder to an active observer of the patterns. It makes me wonder: as we move toward more automated defenses, how many other "leaky" signals like Discord status are we inadvertently broadcasting that define our operational boundaries?
Great read. It’s a vivid reminder that the best security often comes from understanding the intent and timing behind the data, not just the data itself.