IDOR in a REST API leading to mass exposure of personal data
An insecure direct object reference in a REST API endpoint. Changing the sequential numeric identifier in the JSON body returned any user’s complete record.
Summary
The endpoint returned the requested record without checking the authenticated user’s permissions. Walking the range of identifiers would have given access to the entire user database.
With no object-level authorisation (BOLA), a single endpoint exposed every user’s personal data along with their attached documents. The flaw has been fixed.
The CVSS score of 8.6 is based on the verified impact: unauthorised reading of complete records, including identity documents.
Technical details
Endpoint response
Each response returned the complete record for that user, including the attached documents:
{
"record": {
"id": "582941",
"full_name": "[FULL NAME]",
"id_type": "national_id",
"id_number": "[ID DOCUMENT]",
"phone": "[PHONE]",
"email": "[EMAIL]",
"address": "[ADDRESS]",
"organization": "[COMPANY]",
"documents": {
"photo": "PHOTO_582941_[DATE].jpg",
"id_scan": "DOC_582941_[DATE].pdf",
"certificate": "CERT_582941_[DATE].pdf",
"signature": "SIGN_582941_[DATE].tif",
"consent_gdpr": "GDPR_582941_[DATE].pdf"
},
"status": "active"
}
}Automating the attack
A loop over the identifier range automates the extraction:
for record_id in range(500000, 600000):
response = api_request(record_id)
if response.status == "OK":
save_record(response.record)
# name, ID document, phone, email, digital signature...Confidentiality breaches fall within the GDPR enforcement regime. The supervisory authority classifies each case. In Spain that authority is the AEPD.
Impact
- Mass exposure of personal data belonging to every user of the system
- Access to sensitive documents: photographs, identity documents and digital signatures
- GDPR breach through unauthorised access to personal data
- Risk of identity theft using the documentation obtained
- Full enumeration of the user database through sequential identifiers
Remediation
- Object-level authorisation. Verify on every request that the user has permission to access the requested resource.
- Unpredictable identifiers. Replace sequential IDs with UUIDs.
- Per-endpoint rate limiting. Throttle request frequency to make mass enumeration harder.
- Minimise the data in the response. Return only the fields the view needs.
- Logging and alerting. Detect anomalous access patterns on the endpoint.
References
More write-ups
This vector is checked endpoint by endpoint, not with scanner output
Tell us which APIs you want tested. We reply within 24 hours.