October 30, 2026
IDOR in Munshi: Changing a Purchase Inquiry ID Exposed Another User’s Thread
An object-level authorization flaw let an authenticated user open another person’s purchase inquiry and view supplier communication and…

By TheWildEye
4 min read
An object-level authorization flaw let an authenticated user open another person's purchase inquiry and view supplier communication and quotation details.
During a security assessment of Munshi's Purchase Inquiry workflow, I identified a Broken Object Level Authorization (BOLA) vulnerability in the endpoint responsible for retrieving individual inquiry threads.
This was not an authentication bypass. The request was made using a valid, authenticated account. The failure happened after login: the application accepted a user-controlled thread identifier without confirming that the signed-in user was allowed to access that specific inquiry.
By modifying the identifier in the thread URL, the application returned a different purchase inquiry that the account had not created and had no established relationship with. The returned thread exposed supplier communication and quotation-related content outside the account's intended access scope.
The Thread ID Was Treated as Permission
The affected route was:
GET /purchase-inquiry/thread/{thread-id}
Munshi's Purchase Inquiry module uses a thread identifier in the URL to load a conversation between a buyer and a supplier. The expected behavior is straightforward: before returning a thread, the backend must verify that the authenticated user owns the inquiry or has been explicitly granted permission to view it.
During testing, I opened a valid Purchase Inquiry thread and inspected the identifier in the browser URL. I then modified the identifier and reloaded the route. Instead of returning an authorization error, the application loaded a valid thread page.
Figure 1: Purchase Inquiry thread capture. The Munshi host and route are visible; the middle of the thread identifier and private inquiry details are redacted.
A Different Inquiry Was Returned
The key validation was not simply that the modified URL loaded a page. I verified that the application returned a different purchase inquiry.
The report records that the returned thread belonged to another user and had no established relationship with the testing account. The application displayed the thread and its supplier conversation without returning a permission error.
The second screenshot preserves the actual Munshi interface and the message layout. The supplier identity, quotation values, product details, delivery terms, and unrelated recent inquiry entries are covered. The buyer's generic request and the structure of the supplier replies remain visible so the screenshot still shows the application workflow that was accessed.
Figure 2: A different Purchase Inquiry thread shown in the assessment evidence. Supplier identity and commercial details are redacted, while the route suffix remains visible as captured.
This was cross-user access to a distinct business record, not a cosmetic routing issue. The application returned supplier communication and quotation-related content from an inquiry outside the testing account's intended access scope.
What Was Exposed
Purchase Inquiry threads are part of a supplier-facing procurement workflow. They can contain supplier responses, quotations, product details, pricing discussions, availability information, and negotiation context.
The assessment demonstrated unauthorized read access to another user's thread and exposure of supplier communication and quotation-related content. Depending on what an individual thread contains, this type of access can reveal commercial information and business relationships that should remain restricted to authorized participants.
The demonstrated result should be kept distinct from possible broader consequences. The report confirms that a modified identifier returned a different inquiry. It does not demonstrate that the testing account could edit or delete another user's inquiry, nor does it establish access to every tenant's records. Identifier probing or enumeration is a potential concern, but the supplied evidence demonstrates a cross-user retrieval case rather than a full enumeration campaign.
Why This Is BOLA / IDOR
The vulnerability is a Broken Object Level Authorization (BOLA) condition, also commonly called an Insecure Direct Object Reference (IDOR).
The endpoint accepted an object identifier supplied in the URL and used it to retrieve a thread, but the authorization decision was not tied to the authenticated user's ownership or explicit permission for that exact object.
An identifier locates a record. It does not prove that the requester is allowed to view it. Even if identifiers are difficult to guess, the backend must still perform an object-level authorization check on every request. Hiding identifiers or relying on their unpredictability is not a substitute for access control.
The Technical Root Cause
The root cause was the absence of a server-side authorization decision for the requested thread before its content was returned.
The application trusted the object identifier in the URL without verifying that the authenticated user owned the inquiry or had been explicitly authorized to access it. Tenant or session context alone is insufficient unless it is combined with an ownership or permission check for the requested object.
The finding maps to CWE-639: Authorization Bypass Through User-Controlled Key, which describes access to another user's record by modifying an identifier controlled by the requester.
What Needs to Change
The fix belongs at the server-side object boundary, where the thread is resolved and returned.
Every request to load a purchase inquiry thread should verify that the authenticated user owns the inquiry or has explicit permission to view it. This check must happen before any useful thread data is returned.
Unauthorized requests should receive a 403 Forbidden, 404 Not Found, or a generic access-denied response that does not disclose the requested object's contents. The application must not rely on non-guessable identifiers as a replacement for authorization.
Regression testing should cover cross-user access and tenant isolation. A user should be able to load their own permitted threads, while requests for unrelated threads must be rejected even when the supplied identifier refers to a valid record. Automated tests should also cover attempts to probe or enumerate thread identifiers.
Vulnerability Reference
Vulnerability: Unauthorized Access to Purchase Inquiry Threads via BOLA / IDOR
Product: Munshi Purchase Inquiry
Affected endpoint: GET /purchase-inquiry/thread/{thread-id}
Primary CWE: CWE-639, Authorization Bypass Through User-Controlled Key
Closing Thoughts
This issue did not require an unauthenticated request or a complicated exploit chain. The application accepted a request from an authenticated user, trusted the thread identifier supplied in the URL, and returned a conversation that the user was not authorized to view.
The impact was a confidentiality failure in a business workflow: supplier communication and quotation-related information became visible outside the intended access scope.
Every endpoint that retrieves a user-owned resource must verify not only that the requester is authenticated, but also that they are authorized to access that exact object. That check needs to happen on the server, every time the object is requested.
Researcher: Vyom Nagpal