TL;DR
There was no hacker in a hoodie. A freelance marketplace founder found out about their first security incident from a support ticket: a customer asking why he was looking at someone else's dashboard. Behind it sat an authorization check written at 2 AM that never checked anything. The fix took one line. Getting over it took considerably longer.
The Support Ticket
Tuesday morning, coffee, the support queue. One ticket stopped them cold:
"Hi, I logged in and I'm seeing someone else's dashboard. The name at the top says 'Sarah K' but I'm Mark. This is really concerning. What's going on?"
First thought: user error. Mark had probably signed in on the wrong account, or was looking at a stale tab. Second read, though, and the explanation stopped being comfortable.
Reproducing it took three minutes.
What Went Wrong
The bug was embarrassing in its simplicity. One function loaded user data straight off a URL parameter:
/dashboard?user_id=12345
It checked that you were logged in. It never checked that you were the person whose ID you'd just typed into the address bar. Anyone with an account could read anyone else's dashboard by editing a number.
That code got written at 2 AM during a launch crunch. They still remember the thought: "I'll add proper auth checks later." Later never showed up.
The classic IDOR vulnerability: Insecure Direct Object Reference. When you use user-supplied input (like a URL parameter) to access resources without verifying the user has permission to access that specific resource.
The Panic Response
The first hour went badly. Three things in particular:
Mistake 1: Fixing Before Investigating
The instinct is to make it stop. A fix was live within 20 minutes, which felt like competence at the time. It wasn't: the deploy overwrote the only easy way to answer how long the hole had been open and whether anyone had walked through it.
Mistake 2: Not Documenting
No screenshots, no saved logs, nothing preserved before the code changed underneath them. A week later, when the question was "how bad was this," most of the evidence had already rotated out.
Mistake 3: Delaying Customer Communication
Mark's ticket sat for three days under the heading "still investigating." He didn't need the answer that fast. He needed to know a human had read it.
What Should Have Been Done
Looking back, here's the proper incident response sequence:
- Acknowledge the report immediately, even just to say "we're investigating"
- Document everything before making any changes
- Assess the scope: How long has this existed? What data was potentially exposed? Any evidence of exploitation?
- Implement a fix with proper review (not panic-coded)
- Communicate with affected users based on what you found
- Post-mortem: How did this happen and how do we prevent similar issues?
The Investigation
Once the adrenaline wore off, the logs told a kinder story than expected. The hole had been open for six weeks. In that window:
- Zero evidence of anyone systematically exploiting it
- Two instances where users might have accidentally seen other data (both appeared to be URL copy/paste errors)
- No sensitive financial data was exposed (that was in a separate, properly secured system)
That's luck, not diligence. A sequential integer in a URL is the first thing anyone probing the app would have tried.
The Conversation with Mark
They called Mark. It was an uncomfortable ten minutes and absolutely the right call.
His response was surprising: "Thanks for being honest. I've used apps where weird stuff happened and no one ever explained anything. I appreciate you telling me what went wrong and what you fixed."
Mark stayed a customer. He's still one.
What Changed After
Code Review for All Auth Logic
Any code that touches authentication or authorization now gets reviewed by at least one other person. No exceptions, no matter how simple it seems.
The "2 AM Rule"
Nothing ships after midnight anymore. Tired code is where this whole story started. If it genuinely cannot wait until morning, that's usually a sign the deadline was wrong, not the sleep schedule.
Authorization Tests
Automated tests were added that specifically try to access resources as the wrong user. If User A can see User B's data, the test fails.
Incident Response Plan
A simple incident response checklist was written down. When something goes wrong, there's no need to think about what to do. The process is documented.
The real lesson: nobody attacked this app. A tired person shipped a missing if statement and it sat there for six weeks. That is what most incidents actually look like, which is also why most of them are preventable by someone who isn't in a hurry.
For Other First-Time Founders
If you haven't had your first security incident yet, you will. Here's what this founder wishes they'd known:
- It's going to feel terrible. That's normal. Don't let the shame paralyze you.
- Document before you fix. You need to understand the scope before you can properly respond.
- Communicate honestly. Customers can handle bad news. They can't handle feeling deceived.
- Use it as a learning moment. Every incident should result in process improvements.
- Don't build alone. Have someone else review security-critical code.
Write the incident checklist now, while nothing is on fire. Reading one you wrote calmly beats improvising one at 2 AM, which is roughly how this story started.
How do I know if a bug is a security incident?
If unauthorized access to data or systems was possible, it's a security incident, even if no one exploited it. Treat potential exposures seriously and investigate properly.
Should I tell customers about security issues?
Generally, yes. If their data was potentially exposed, they have a right to know. How you communicate matters too. Be honest, specific about what happened, and clear about what you've done to fix it.
What's an IDOR vulnerability?
Insecure Direct Object Reference (IDOR) happens when an application uses user input to directly access objects (like database records) without checking if the user should have access. It's one of the most common web vulnerabilities.
How do I prevent authorization bugs?
Always verify that the current user has permission to access the specific resource they're requesting. Don't just check if they're logged in. Check if they should see that particular data. Write tests that try to access resources as the wrong user.
Find Issues Before Your Users Do
Scan your application for common vulnerabilities like IDOR and broken authorization.