IDOR
ANTS Breach: 19M French Citizens Exposed via IDOR
What Happened on April 15, 2026
France's national secure document agency, ANTS (Agence Nationale des Titres Sécurisés, also known as France Titres), was hit by a major breach on April 15, 2026. Attackers exploited an IDOR (Insecure Direct Object Reference) vulnerability in the agency's public-facing API, exposing the personal data of 19 million French citizens: full names, email addresses, and dates of birth.
This isn't a sophisticated nation-state attack. It's a textbook access control failure — the kind that ships in production every single day.
What Is an IDOR Vulnerability?
IDOR stands for Insecure Direct Object Reference, and it sits at the top of the OWASP Top 10 as A01:2021 – Broken Access Control. The concept is brutally simple: an API exposes an object identifier (a database ID, a filename, a UUID) in a request, and fails to verify whether the authenticated user is authorized to access that specific object.
Here's what the vulnerable request likely looked like:
GET /api/v1/dossiers/4872301
Authorization: Bearer <valid_user_token>
By incrementing the ID — 4872302, 4872303, and so on — an attacker retrieves records belonging to other citizens. No zero-day. No sophisticated exploit chain. Just a for loop:
import requests
headers = {"Authorization": "Bearer STOLEN_TOKEN"}
for record_id in range(4000000, 5000000):
r = requests.get(f"https://api.antsfr.fr/dossiers/{record_id}", headers=headers)
if r.status_code == 200:
print(r.json())
At scale, this kind of automated enumeration can exfiltrate millions of records in hours.
Why This Breach Is Particularly Severe
ANTS manages French passports, national ID cards, driver's licenses, and vehicle registration certificates. The combination of name + email + date of birth is the classic trifecta for:
- Targeted phishing and social engineering (attackers know your exact details)
- Identity fraud in administrative and financial processes
- Credential stuffing when cross-referenced with other leaked databases
For 19 million people, the blast radius here is enormous. French authorities notified the data protection authority CNIL within the mandatory 72-hour window (GDPR Article 33), and ANSSI (France's national cybersecurity agency) was immediately brought in for forensic investigation.
Under GDPR, penalties for a breach of this nature can reach €20 million or 4% of global annual turnover — whichever is higher.
The Three Technical Failures That Made This Possible
An IDOR vulnerability of this scale on a government API in 2026 isn't a single mistake — it's a systemic failure across development, QA, and operations.
1. Authorization never checked at the object level
The API correctly verified authentication (is this a valid token?) but completely skipped authorization (does this token's owner have rights to this specific record?). This AuthN/AuthZ gap is the root cause.
2. Sequential, predictable integer IDs
Using auto-incrementing integers as public-facing identifiers is a design antipattern. While switching to UUIDs (f47ac10b-58cc-4372-a567-0e02b2c3d479) doesn't fix the authorization flaw, it makes enumeration computationally infeasible and buys critical time.
3. No rate limiting or anomaly detection
Millions of sequential requests to the same endpoint pattern should trigger alarms long before exfiltration completes. The absence of any behavioral monitoring allowed the attack to run at scale undetected.
The Secure vs. Vulnerable Pattern
# ❌ VULNERABLE — as deployed at ANTS
@app.get("/dossiers/{dossier_id}")
def get_dossier(dossier_id: int, current_user: User = Depends(get_current_user)):
# Authenticates the user, but never checks ownership
return db.query(Dossier).filter(Dossier.id == dossier_id).first()
# ✅ SECURE — what should have been there
@app.get("/dossiers/{dossier_id}")
def get_dossier(dossier_id: int, current_user: User = Depends(get_current_user)):
dossier = db.query(Dossier).filter(
Dossier.id == dossier_id,
Dossier.owner_id == current_user.id # ← the one line that prevents the breach
).first()
if not dossier:
raise HTTPException(status_code=404) # 404 not 403 — don't confirm existence
return dossier
One .filter() clause. That's the difference between a secure API and a 19-million-record breach.
Your IDOR Prevention Checklist
If you're shipping APIs that handle user-owned resources, run through this before your next deployment:
- Every data-fetching endpoint filters by both object ID and current user ID
- Public-facing IDs are UUIDs or opaque tokens, not sequential integers
- Rate limiting is enforced at the API gateway (100 req/min per token is a reasonable starting point)
- Access logs capture user identity alongside resource IDs for anomaly correlation
- Authorization checks are tested in CI/CD, not just manually
How Scorra Catches IDOR Before It Ships
IDOR is notoriously hard for traditional scanners to catch because it requires understanding application-level context — not just HTTP response codes. Scorra approaches this differently by:
- Automatically substituting object identifiers across URL parameters, path segments, and request bodies
- Comparing responses across user contexts to detect when User A can access User B's data
- Flagging sequential ID patterns in API responses as a high-severity finding
- Mapping AuthN/AuthZ gaps across every discovered endpoint
In the ANTS scenario, a pre-production Scorra scan would have detected that /dossiers/{id} returns 200 responses with different users' data — a clear IDOR signature — before a single line of this code ever reached production.
What You Should Do Right Now
If you're a developer or technical lead:
- Search your codebase for patterns like
.filter(Model.id == request_id)without an ownership check - Replace all sequential integer IDs in public-facing APIs with UUIDs
- Add authorization tests to your integration test suite — not just happy-path tests
- Set up rate limiting on every API endpoint, today
If you used ANTS services before April 2026:
- Be suspicious of any email that references your exact personal details
- Enable 2FA on your email and financial accounts immediately
- Monitor your credit and bank accounts for unusual activity
The ANTS breach is a wake-up call. Broken access control has been the #1 web application vulnerability for five consecutive years. It's not going away — but it is entirely preventable with the right tooling and discipline.
Don't wait for a breach to find your IDOR vulnerabilities. Run a free scan on scorra.io and get a full access control audit of your API in under 5 minutes.