October 1, 2026
Broken Object Level Authorization (BOLA / IDOR) in Linktree GraphQL API Allows Unauthorizedβ¦
Overview
By Ahemd ashraf
2 min read
Overview
During security testing of Linktree's GraphQL API, I identified a Broken Object Level Authorization (BOLA/IDOR) vulnerability that allowed an authenticated user to modify a Link object that was outside their authorized workspace.
The issue was caused by insufficient server-side authorization checks around a user-controlled Link identifier.
Affected Endpoint
POST https://graph.linktr.ee/graphqlPOST https://graph.linktr.ee/graphqlThe vulnerable functionality was exposed through GraphQL mutations responsible for managing Link objects.
Discovery
While testing Link management functionality, I noticed that requests contained a Link identifier that was supplied to the GraphQL API.
I first performed the operation against a Link belonging to my own workspace and captured the request.
I then modified the Link identifier and supplied the identifier of another Link that was outside my authorized workspace.
One of the tested object identifiers was:
582743627582743627The application accepted the modified identifier and processed the request against the referenced Link.
This indicated that the backend was not properly verifying whether the authenticated user was authorized to manage the referenced object.
Proof of Concept
The testing process was straightforward.
Step 1 β Legitimate Request
I authenticated with an account that had permission to manage Links in my own workspace.
I then captured the GraphQL request responsible for modifying the Link.
The request contained a Link/object identifier.
Step 2 β Modify the Object Identifier
I replaced the original Link ID with the ID of a Link belonging to another workspace.
For example:
Original Link ID:
<my-authorized-link-id>
Modified Link ID:
582743627Original Link ID:
<my-authorized-link-id>
Modified Link ID:
582743627No victim credentials were required.
Step 3 β Send the Modified Request
The modified GraphQL request was sent using the same authenticated session.
Instead of rejecting the request because the Link belonged to a different authorization scope, the server processed the operation against the supplied object.
The affected functionality was associated with the following GraphQL mutation:
setDigitalDownloadLinkContextsetDigitalDownloadLinkContextThe mutation operated on Link-related properties such as:
id
title
url
active
statusid
title
url
active
statusResult
The operation was successfully performed against the referenced Link despite the authenticated account not having authorization over that Link.
This demonstrated an object-level authorization failure.
Why This Happens
The application correctly authenticated the requester, but authentication alone does not establish authorization over every Link object.
The server should have established a relationship similar to:
Authenticated User
β
Authorized Workspace
β
Requested Link
β
Permission to modify that LinkAuthenticated User
β
Authorized Workspace
β
Requested Link
β
Permission to modify that LinkInstead, the supplied Link identifier was trusted without sufficiently validating that relationship.
Impact
An attacker with a valid account could potentially manipulate Link objects outside their authorized workspace by supplying identifiers belonging to other users or workspaces.
Depending on the affected Link, this could result in:
- Unauthorized Link modification
- Link defacement
- Replacement of legitimate URLs
- Redirecting visitors to attacker-controlled destinations
- Phishing opportunities
- Unauthorized modification of digital-product links
- Cross-workspace integrity violations
The demonstrated security boundary violation is that authorization was not properly enforced at the Link-object level.
Root Cause
The root cause was insufficient server-side object-level authorization.
The GraphQL resolver accepted a Link identifier supplied by the client but did not adequately verify that the authenticated user had permission to perform the requested operation on that specific Link.
A valid object ID should never be treated as proof that the requester is authorized to access or modify the object.
Remediation
Every GraphQL resolver or mutation that accepts a Link identifier should perform an explicit server-side authorization check.
Before modifying a Link, the backend should:
- Resolve the requested Link.
- Determine the workspace/account that owns the Link.
- Determine the authenticated user's workspace and permissions.
- Verify that the user has the required permission for the requested operation.
- Reject the request if the authorization relationship does not exist.
The authorization check should be performed server-side for every request and should not depend on frontend restrictions.
Conclusion
This finding demonstrates why GraphQL APIs require strict object-level authorization.
An authenticated user should not automatically be trusted to access or modify an object simply because they can supply its identifier.
For penetration testers, a useful test case is to capture a legitimate request, identify object-level identifiers, and replay the request with an identifier belonging to another authorization scope.
If the server processes the request instead of rejecting it, this may indicate a BOLA/IDOR vulnerability.