Short summary:
In products that use the same real-time collaboration system as Google Docs, an attacker could take over other user’s “real-time sessions”. This means that the attacker could chat, move the cursor, and perform other collaboration-related actions in the name of any victim.
POC Video:
https://youtu.be/q34AZ3I4gK8 - 2:37
Core Issue:
The real-time collaboration system uses a custom 16 char long session ID to authenticate users. When a user opens e.g. a Docs document, the page starts polling the /bind
endpoint, which returns as soon as a new event occurs on the document.
The core issue is that the events received by this endpoint almost always contain the session ID of the event initiator. For example, if a new user joins the document, everyone who already has the document open will receive a user object with the new user’s name, profile picture, and among others, with the new user’s session ID.
The obtained session ID then can be used to perform real-time actions in the name of that user.
Steps to reproduce:
This is a written version of the attack performed in the POC video.
- Install Burp Suite
- Create 3 new users,
Attacker
,Victim
, andObserver
- Only start proxying
Attacker
’s traffic with Burp - With
Victim
, Create a new Document, and inviteAttacker
andObserver
asEditor
s - Open the document in all 3 browser windows
- Refresh
Victim
’s page to generate a new join event on the/bind
endpoint - In Burp, look for new
/bind
responses, and find the one that includesVictim
’s user object - Note the
Victim
’ssid
from the user object, andAttacker
’ssid
from the/bind
request’ssid
parameter - Go to
Proxy
->Options
->Match and Replace
and clickAdd
- Set the type to
Request first line
, setMatch
toAttacker
’ssid
, setReplace
toVictim
’ssid
, and clickOK
- With
Attacker
, send a new chat message - With
Observer
, open the chat pane, and see that the message was sent byVictim
- With
Attacker
, start typing and/or selecting text - With
Observer
, see that it looks likeVictim
is selecting/editing the document
Extra Attacks:
- Other actions can also be performed when the attacker has the victim’s session ID. For example, using the
/leave
endpoint, the victim can be “kicked off” from the document, making her invisible for the other users (but can still edit). Any other endpoint that authenticates with that session ID is probably vulnerable, like/active
. - Moving the cursor requires
Editor
orCommenter
privileges, so a normalViewer
can’t move the cursors ofEditor
s, since the permission is checked on a Google session level. But, endpoints like/chat
and/leave
can be used byViewer
s as well. I was able to chat in the name of any editor with an anonymous (not logged in) account when the document was link-shared with theViewer
permissions. That is interesting, since by design onlyEditor
s andCommenter
s should be able to chat, other roles can’t even see the chat pane. - Changing the
sid
(fromAttacker
’s toVictim
’s) in thebundles
object when making an edit withAttacker
will crashVictim
’s page, with the messageUnable to load file - Try to load it again or send an error report.
. OtherViewer
s will not crash, and if they have theLive edits
accessibility pane enabled, they will see that the edit was made byVictim
. The edit initiator (Attacker
) will be correctly shown in theVersion history
.
Limitations:
- Changing the
sid
in theRequest first line
only changes the user of theselection
commands. So, it looks likeAttacker
is typing in the name ofVictim
, but actually,Attacker
is only moving the cursor in the name ofVictim
, and editing using her own account. So, checkingVersion history
will correctly show that the edits were made byAttacker
. - In my research, I wasn’t able to trick the
Version history
using these session IDs, as it is most likely checking the user’s full Google session.
[Disclosure Warning]:
This is a new system I am experimenting with:
This issue is subject to a 90 day disclosure deadline. On 2021-04-20
this issue with all additional comments will be publicly disclosed. Sensitive details from the report/comments such as names/email addresses will be redacted. If you would like to redact additional information or if for some reason the issue can’t be fixed until the deadline, let me know in a comment.
Thank you!