October 10, 2026
I Found an IDOR in a Government Consular Portal: 700,000 Records, Sensitive Data, and a Serious…
The story of investigating a record-level access-control weakness, analyzing the exposed functionality, and understanding why a single…

By PYHACKER
8 min read
The story of investigating a record-level access-control weakness, analyzing the exposed functionality, and understanding why a single missing authorization check can have consequences far beyond one HTTP request.
The Beginning: A Small Observation That Raised Bigger Questions
Some security findings begin with a complicated attack chain. Others begin with a simple question:
What happens when an application trusts a record identifier without verifying who is requesting it?
During a web application security investigation, I examined a consular registration portal associated with the Ministry of Foreign Affairs of a redacted country.
The application provided functionality for viewing and managing consular registration records. While examining one of these pages, I noticed that the URL contained a record identifier.
That observation alone did not establish a vulnerability. Applications routinely use identifiers to locate resources.
What mattered was the authorization boundary: could the application establish that the requester was entitled to access the particular record?
As I investigated the behavior, I identified an apparent Insecure Direct Object Reference (IDOR) issue, also described in API security as Broken Object Level Authorization (BOLA).
The concern extended beyond viewing information. Related functionality raised questions about whether unauthorized users could also modify or delete records.
The investigation became a case study in three fundamental security properties:
- Confidentiality: Protecting sensitive applicant information.
- Integrity: Preventing unauthorized changes to registration records.
- Availability: Preventing unauthorized deletion or disruption.
The organization, country, production domain, and identifying record details are intentionally redacted in this article.
1. Understanding the Application's Attack Surface
The functionality under investigation was associated with a route following this pattern:
https://[REDACTED-GOVERNMENT-DOMAIN]/public-register-request-edit/[RECORD-ID]
The route suggests that a record identifier is used to locate a particular registration entry.
The page I examined displayed several categories of information, including:
- Applicant identification and contact details.
- Passport-related information.
- Consular registration identifiers.
- Application status.
- Registration and processing dates.
This immediately made authorization an important part of the investigation.
A registration record containing ordinary public information presents a different risk from a record containing personal contact details and passport-related identifiers.
However, the presence of sensitive information does not itself prove an IDOR. The important technical question is whether the server permits a requester to access a record outside their authorized scope.
That became the central question of the investigation.
2. The Vulnerability: Broken Object-Level Authorization
IDOR occurs when an application references an object but fails to properly verify the requester's permission to access or manipulate it.
Consider a hypothetical registration system:
GET /api/registrations/1042
The server uses the identifier 1042 to retrieve a registration record.
In a secure application, the server must also determine whether the current user is allowed to access that record.
If the server simply retrieves whichever record the supplied identifier references, without enforcing the appropriate authorization policy, the application may expose other users' information.
The key distinction is:
Authentication answers who the requester is. Authorization determines what that requester is allowed to do.
An application can implement authentication correctly and still contain a serious authorization vulnerability.
Similarly, changing an identifier is not inherently an exploit. The vulnerability exists when the server accepts a request for an object the requester is not permitted to access.
3. How I Approached the Investigation
I approached the finding as an authorization problem rather than assuming that the identifier itself was the root cause.
A useful investigation needs to answer several questions:
- Which application functionality retrieves the record?
- What information does the response contain?
- What authorization restrictions should apply?
- Does the server enforce those restrictions?
- Are related modification and deletion operations subject to equivalent checks?
- What is the actual scope of the issue, and how can it be established without causing additional harm?
- These questions help separate an interesting observation from a defensible security finding.
Tooling and analysis
The relevant tools for this type of investigation include:
Browser Developer Tools
Useful for understanding the application workflow, inspecting network requests, and determining which routes are involved in retrieving registration details.
Burp Suite
Useful for examining HTTP requests and responses, understanding application behavior, and comparing the expected and observed authorization outcomes in an authorized test environment.
Python
Useful for organizing sanitized observations, processing approved test data, comparing response structures, and producing evidence summaries. Automated collection should be limited to expressly authorized data and scope.
HTTP and application-response analysis
The response should be examined for the information returned, the application's access-control behavior, and whether unauthorized requests are correctly rejected. A successful HTTP response alone does not prove an authorization vulnerability; the response must be evaluated against the requester's permissions.
The objective is not simply to find an interesting URL. It is to establish the application's actual security boundary.
4. The Scale of the Finding
The investigation raised concerns about the potential scale of the exposure, with approximately 700,000 records reported as being within the affected scope.
I also wrote a Python script during the investigation that I report collected records at scale.
This changes the risk assessment considerably if unauthorized access to those records is confirmed. A weakness affecting a single object can become a systemic data-exposure problem when the same authorization failure applies across a large collection of objects.
There is an important distinction between three quantities:
- The number of records potentially affected by the vulnerability.
- The number of records actually retrieved during testing.
- The total number of records held by the application.
These numbers should not be treated as interchangeable.
The approximately 700,000-record figure should be understood in the context of what was actually retrieved and verified, rather than automatically interpreted as the total database size.
I am not publishing the scraping script, bulk-extraction requests, or operational details that would enable someone else to collect applicants' personal information.
The technical lesson remains significant: automation can magnify the consequences of an authorization failure, turning an individual-record weakness into a potentially large-scale privacy incident.
5. What Makes the Exposed Information Sensitive?
The registration page displayed information associated with consular applications.
Depending on the record, the fields included categories such as:
Data categorySecurity concernApplicant identificationPersonal privacy and potential identity-related misuseContact informationTargeted phishing and unwanted contactPassport-related informationExposure of sensitive travel-document identifiersConsular registration identifiersCorrelation of records across application workflowsApplication statusDisclosure of personal administrative informationRegistration and processing datesAdditional contextual information about an applicant
The risk does not depend on whether every individual field is secret in isolation.
When multiple fields are exposed together, they can provide a more detailed picture of an individual's identity and interactions with a government service.
That is why object-level authorization must be enforced before the application returns the record.
6. The Second Concern: Record Modification
The investigation also raised concerns about the application's record-editing functionality.
Read access and write access are separate permissions.
An application may prevent unauthorized viewing through one route but still have an update operation that fails to verify ownership or administrative privileges.
If that weakness exists, a requester might be able to change information belonging to another applicant.
Possible consequences include inaccurate registration details, administrative confusion, and disruption to application processing.
To assess this properly, an authorized test must establish whether the server accepts an unauthorized change to a synthetic record. The impact should not be demonstrated by modifying real applicants' information.
7. The Third Concern: Record Deletion
The presence of deletion functionality raised another important question: does the server verify authorization before removing a registration record?
Deletion is not merely another form of data access. It can affect the availability and integrity of the service.
If a deletion operation does not enforce appropriate permissions, unauthorized actions could potentially disrupt applicants' registration records.
However, the existence of a delete option is not proof that an attacker can delete other users' records. That conclusion requires separate evidence showing that the authorization control is missing or ineffective.
For that reason, read, update, and deletion findings should be documented independently, even when they appear to originate from the same underlying design flaw.
No real applicant records should be deleted to establish this behavior.
8. Steps to Reproduce — Safe Authorization Validation
The following workflow describes how to validate the underlying issue in an explicitly authorized environment. It deliberately avoids production-record enumeration and destructive actions.
Step 1 — Establish the test scope
Obtain authorization to assess the specific application and identify the permitted accounts, records, and operations.
Step 2 — Identify the relevant route
Locate the registration-record functionality and document the route structure using a placeholder such as:
/public-register-request-edit/[RECORD-ID]
Do not include a live production identifier in the public report.
Step 3 — Establish the expected permissions
Use two designated test accounts and synthetic registration records. Determine which records each account is permitted to access.
Step 4 — Verify record-level authorization
Request a test record outside the requesting account's permitted scope. Compare the observed response with the application's expected authorization policy.
A secure implementation should deny access to the unauthorized record.
Step 5 — Assess modification permissions separately
In the authorized test environment, use a synthetic record to verify that an account cannot modify a record it does not own or administer.
Step 6 — Assess deletion permissions separately
Verify the deletion authorization policy using an isolated, disposable test record or an approved non-destructive test procedure.
Do not attempt mass deletion or modification of production records.
Step 7 — Preserve the evidence
Record sanitized requests, responses, account permissions, timestamps, and redacted screenshots. Include only the minimum evidence needed to demonstrate the issue.
This approach provides a reproducible technical finding without unnecessarily exposing personal information.
9. Root Cause Analysis
The likely underlying design weakness is insufficient object-level authorization.
A secure record-management operation must not treat a supplied identifier as proof that the requester is authorized.
The server should enforce the relevant permission every time a protected resource is accessed or modified.
For example, the authorization decision should account for:
- The authenticated identity.
- Ownership of the requested record.
- The user's assigned role.
- The particular action being requested.
- Any additional restrictions required by the application.
Authorization checks should be implemented on the server and applied consistently across related operations.
Random identifiers may make enumeration more difficult, but they cannot replace proper authorization.
10. Remediation Recommendations
Enforce object-level authorization
Verify the requester's permission for every record retrieval, update, deletion, and export operation.
Apply least privilege
Users should only access their own records unless a defined and authorized administrative role permits broader access.
Audit related routes
Review other endpoints that interact with the same registration objects. A fix applied to one route may not address similar weaknesses elsewhere.
Investigate potential historical access
The organization should review available application, gateway, and database logs to determine whether unauthorized access or modifications occurred.
Minimize sensitive data returned
Only return fields required by the specific workflow. Apply appropriate protections to passport-related information and other sensitive identifiers.
Introduce automated regression tests
Tests should verify that unauthorized access, modification, and deletion requests are consistently rejected.
Establish monitoring and response procedures
Investigate unusual access patterns, unexpected record changes, and authorization failures. If exposure is confirmed, assess the scope and any applicable notification obligations.
11. Responsible Disclosure
Security research should improve security without unnecessarily increasing risk to the people affected.
When an investigation identifies a potential authorization weakness involving personal information, the appropriate response is to stop unnecessary access, avoid destructive testing, preserve minimal redacted evidence, and report the issue through an appropriate security contact.
The responsible organization should be given an opportunity to investigate the underlying behavior, determine the actual scope, and remediate the vulnerability.
The country, ministry-specific identifying information, production domain, individual record identifiers, and applicant details have been withheld from this publication.
Conclusion
This investigation demonstrates why authorization deserves as much attention as authentication.
A record identifier may look like a small implementation detail, but if the application does not enforce the correct permissions, it can become a gateway to information that should remain protected.
When the same weakness affects record-management operations, the potential consequences may extend to data exposure, unauthorized changes, and disruption of service.
The most important lesson is not that a particular identifier was accessible. It is that every sensitive operation must enforce authorization at the object level, on the server, every time.
For developers, this means implementing consistent access-control checks and regression testing. For security researchers, it means validating the actual impact, documenting evidence accurately, and protecting the people whose data is at risk.
Disclosure note: Organization-identifying details, live production identifiers, personal data, and bulk-extraction instructions are intentionally omitted. All impact statements should be interpreted according to the behavior independently verified during authorized testing.
#CyberSecurity #IDOR #BOLA #AppSec #OWASP #WebSecurity #PenetrationTesting #ResponsibleDisclosure