What is IDOR? The bug that lets anyone read your users' data by changing one number
Short answer
IDOR (insecure direct object reference) is when your app takes an ID from the request, say /invoices/1043, and returns that record without checking the logged-in user is allowed to see it. Change the number to 1044 and you are reading a stranger's invoice. Guessable IDs make it easier to exploit, but they are not the bug: the missing ownership check is. Random IDs slow a guesser down; one condition in the query shuts the door.

Part of the article Pick a UUIDv7 library that keeps order: 10 tested, .NET fails 50%. This page answers one question from it in depth.
On this page · 11 sections
The current fear is that AI-written apps leak data. Some do. But the most famous IDOR on record came from one of the biggest US title insurers in 2019, built by humans, and it exposed about 885 million files. The bug is old, boring and fixable in one line, whoever wrote the code.
Key numbers
| What | Number | Source (checked Oct 25 2026) |
|---|---|---|
| OWASP Top 10 rank of broken access control (IDOR's category) | #1 in 2021 and 2025 | OWASP Top 10 2025, A01 |
| Applications tested with some form of it, 2021 / 2025 | 94% / 100% | 2021 A01, 2025 A01 |
| Occurrences in OWASP's data, 2021 / 2025 | 318,487 / 1,839,701 | same |
| First American files exposed, no login needed | about 885 million, going back 16+ years | KrebsOnSecurity, May 24 2019 |
| SEC penalty for First American | $487,616 | SEC, June 15 2021 |
| CVEs tagged CWE-639 or CWE-862, 2026 through Oct 24 | 1,227 (vs 645 in all of 2023) | our NVD API pull, Oct 25 2026 |
| Their share of all CVEs published in 2026 | 1.38% of 88,641 | same |
| Fresh random bits per UUIDv7, by library | 32 to 74 (UUIDv4: 122) | our UUIDv7 library test, Oct 23 2026 |
What IDOR looks like
Three ingredients, per the OWASP IDOR cheat sheet: an object (an account, a document, a ticket), a reference to it in the URL or request body, and a server that never asks whether this user may touch that object.
The whole bug and the whole fix. Same URL, same ID scheme, one extra condition. Diagram by Tensorust.
The login works. The session is valid. The user is exactly who they say they are. That is why IDOR slips past people: authentication passed, authorization was never asked. MITRE files it as CWE-639, Authorization Bypass Through User-Controlled Key. PortSwigger notes the term was popularized by the OWASP Top Ten back in 2007. In API security, OWASP renames it BOLA (broken object level authorization) and ranks it API1:2023, with exploitability, prevalence and detectability all rated easy or widespread.
The 885-million-file version
On May 24, 2019, real estate developer Ben Shoval showed KrebsOnSecurity that a document link First American Financial had emailed him worked for everyone. Changing the document number "in either direction yielded other peoples' records", Krebs wrote, suggesting the numbers were issued sequentially. The earliest went back to 2003. No authentication was required. The files included bank account numbers, wire records and Social Security numbers.
Follow the money afterward. The SEC's 2021 order was about disclosure controls, not the bug itself: First American's senior executives were not told that the company's own security staff had found the vulnerability several months earlier and had not fixed it. The penalty was $487,616. For a company of that size, the price of 16 years of customer files sitting one number apart was a rounding error. Nobody is coming to save your users; the check has to be in your code.
Are guessable IDs the problem?
Partly, and this is where people over-learn the lesson. Sequential IDs turn IDOR from a bug into a free download: add 1, repeat. Random IDs raise the cost of guessing. Our UUIDv7 library test measured how many fresh random bits each popular library puts in every ID once an attacker knows the creation millisecond:
Fresh random bits per ID, measured on 1 million IDs per library, Oct 23 2026. UUIDv4's 122 bits are from RFC 9562. Every row is in the parent article's data.
32 bits is 4,294,967,296 possibilities. At 1,000 guesses a second, sweeping them takes about 49.7 days per millisecond of creation time, and a rate limit stretches that further. So UUIDs do stop the "add 1" attack. That is real.
What they do not stop is everything else. IDs leak: in shared links, invoice emails, browser history, analytics, support screenshots, referrer headers and logs. First American's own customers were emailed working links. The moment an ID is known, randomness is worth zero. That is why RFC 9562 says implementations "SHOULD NOT assume that UUIDs are hard to guess" and "MUST NOT" use them as security capabilities, and why OWASP's cheat sheet says access control checks stay "essential" even with complex identifiers. Pick UUIDv7 or UUIDv4 for your database's sake. Do not pick them for security.
What the CVE record shows
We counted every CVE in the NVD tagged CWE-639 (the IDOR entry) or CWE-862 (missing authorization), by year published, through October 24, 2026.
- 2026 so far: 1,227 missing-authorization CVEs (285 CWE-639, 942 CWE-862), already almost double the busiest full year we pulled, 2023 at 645.
- That is 1.38% of the 88,641 CVEs published this year, against 2.08% in 2023. The share is not exploding; the whole CVE pile is. NVD published 49,972 CVEs in all of 2025 and 88,641 in 2026 through October 24.
- 2024 and 2025 dipped to 283 and 118. A CWE tag depends on who filed and analyzed each record, so treat single-year swings with care.
Our read: more software is shipping, and more people and tools are hunting for exactly this bug, because it is the cheapest one to find. A researcher with two test accounts finds it in an afternoon. That cuts both ways: whoever ships faster gets found faster.
How to fix it
- Scope every lookup to the user. Query by the object's ID and the current user's ID (or team, or role) together. No match returns 404, so you do not even confirm the record exists.
- Do it on the server, on every endpoint. Reads, updates, deletes, exports, file downloads, GraphQL resolvers and background job triggers. Hiding a button in the UI is not a check.
- On Supabase, turn on row-level security. Its docs say that once RLS is enabled, no data is accessible through the API with a publishable key until you create policies. Without it, the auto-generated API is an IDOR on every table.
- Take the user from the session, never from the request. OWASP's BOLA page warns that just comparing a user ID in the token to an ID in the URL covers only a small subset of cases; look up what that user actually owns. Our JWT decoder shows which user a token claims to be.
- Test with two accounts. Log in as user A, copy an ID, log in as user B, paste it. Do that for every object type. It takes minutes and it is the test that finds this bug.
Common misconceptions
"We use UUIDs, so we are safe."
The recordUUIDs stop sequential guessing, not leaked links. RFC 9562 itself says not to treat them as hard to guess, and the 32-bit libraries in our test give a guesser far less to beat than the 122 bits people assume.
"Users have to log in first, so it is fine."
The recordIDOR is a logged-in bug. The attacker is a normal user reading other users' data. Authentication answers who you are, not what you may open.
"This is an AI-code problem."
The recordThe OWASP data found broken access control in 94% of tested apps in 2021, before AI app builders went mainstream, and the biggest IDOR on record was hand-built. AI tools ship the same mistake faster; they did not invent it.
"Only APIs have IDOR."
The recordFile downloads, PDF links, image URLs and admin pages all carry object references. First American's leak was document images.
What this means for you
Before you launch, open your app in two browsers with two accounts and swap every ID you can find between them. If anything loads that should not, fix the query, not the ID format. If your app is built on Lovable, Bolt or Supabase and you would rather have someone else do this, our $49 Launch Check checks whether a stranger can read your tables, plus storage, logins and secret keys, in plain English within 48 hours; if a problem in what we checked turns up after your report, we write the fix at no extra cost.
Related
- Pick a UUIDv7 library that keeps order: 10 tested: the parent test and the random-bits data.
- UUIDv7 vs UUIDv4 and UUID vs Nano ID: pick the ID for the database, not for security.
- 429 Too Many Requests: rate limits that slow down guessers.
- Lamport clock vs vector clock: what time-ordered IDs can and cannot prove.
- OpenClaw vulnerabilities and npm advisories: how advisories get counted.
FAQ
What is an IDOR vulnerability?
IDOR stands for insecure direct object reference. It happens when an app takes an ID from the request, such as /invoices/1043, and returns that record without checking that the logged-in user is allowed to see it. Changing the number to 1044 shows someone else's data. MITRE files it as CWE-639, Authorization Bypass Through User-Controlled Key.
Do random IDs like UUIDs prevent IDOR?
They make guessing harder, not impossible, and they do nothing once an ID leaks through a shared link, an email, a log or a browser history. OWASP's IDOR cheat sheet says access control checks are essential even with complex identifiers, and RFC 9562 says UUIDs must not be used as security capabilities.
How do you fix IDOR?
Check ownership or permission on every request, on the server, for every object: look the record up by its ID and the current user's ID together, and return 404 when there is no match. In Supabase, that means row-level security policies on every exposed table. Then test with two accounts by swapping IDs between them.
Is IDOR the same as broken access control?
IDOR is one kind of broken access control, which ranks number 1 in the OWASP Top 10 for both 2021 and 2025. In the 2025 edition, 100% of the applications tested had some form of broken access control. In API security, OWASP calls the same bug BOLA, broken object level authorization, and ranks it API1.
What was the First American IDOR breach?
In May 2019, developer Ben Shoval and KrebsOnSecurity found that First American Financial's site exposed about 885 million title insurance files, going back more than 16 years, with no login. Changing the document number in a link showed other people's records. The SEC later fined the company $487,616 over its disclosure controls.
Sources
All checked October 25, 2026.
Standards and rankings
- OWASP, Top 10 2025, A01 Broken Access Control: #1, 100% of tested applications, 40 CWEs, 1,839,701 occurrences, 32,654 CVEs, IDOR named in the description.
- OWASP, Top 10 2021, A01 Broken Access Control: 94% of applications tested, 3.81% average incidence, 318,487 occurrences, 19,013 CVEs.
- OWASP, API Security Top 10 2023, API1 Broken Object Level Authorization.
- OWASP Cheat Sheet Series, Insecure Direct Object Reference Prevention: the three ingredients; access control checks stay essential with complex identifiers.
- MITRE, CWE-639: Authorization Bypass Through User-Controlled Key, with IDOR as the alternate term.
- PortSwigger Web Security Academy, Insecure direct object references (IDOR): the term popularized by the OWASP 2007 Top Ten.
- IETF, RFC 9562, section 8 Security Considerations: UUIDs should not be assumed hard to guess and must not be used as security capabilities.
- Supabase, Row Level Security.
The First American case
- Brian Krebs, First American Financial Corp. Leaked Hundreds of Millions of Title Insurance Records, KrebsOnSecurity, May 24, 2019, with the finding credited to Ben Shoval.
- U.S. Securities and Exchange Commission, press release 2021-102, June 15, 2021: over 800 million images back to 2003, executives not told security staff had found the flaw several months earlier, $487,616 penalty.
Our data
- NVD CVE API 2.0 (docs): totalResults for cweId CWE-639, cweId CWE-862 and all CVEs, by publication date in quarterly windows, 2016 to October 24, 2026, pulled October 25, 2026. Every count is in data.csv on this page.
- Random bits per ID: Pick a UUIDv7 library that keeps order, 1,000,000 IDs per library, October 23, 2026. Guessing time is our arithmetic (2^32 at 1,000 guesses a second).
Images
- Charts and code diagram by Tensorust from the data above.
Next question
Every number on this page links to its source and was checked on Oct 25, 2026. Spot an error or a newer figure? Email matt@tensorust.com and it gets fixed. Related: $49 Launch Check for Lovable, Bolt and Supabase apps, JWT decoder (see which user a token claims).
Read next
- Article · Oct 23, 2026Pick a UUIDv7 library that keeps order: 10 tested, .NET fails 50%
- Article · Oct 24, 2026OpenClaw got 591 advisories. 1 in 4 top npm installs is the real hole
- Article · Oct 18, 2026Exponential backoff with jitter: 64 of 100 LLM calls still failed
- Explainer · Oct 25, 2026Lamport clock vs vector clock: what each one can actually prove
- Guide · Oct 25, 2026UUID as a primary key in Postgres: use uuidv7(), store it as uuid, and measure
Get the next one by email.
What my AI agents tried this week, with the real numbers: what worked, what flopped, what made money. One email when there is something worth reading.
No spam, never sold. Every email has a one-click unsubscribe.