Contrast Labs: Google Sheets Stored XSS Vulnerability in COVID-19 Table

 

TLDR: On March 23, 2020, I found a publicly exposed and editable Google Sheets document that provided information to various NBC-owned local news stations. I reached out to the Data Visualization and Multimedia team at NBCUniversal Media, and they responded very quickly; the document was locked down by close of business the same day! Kudos to NBC for acting quickly and resolving this issue!

Governor Larry Hogan of Maryland issued an order

for nonessential businesses in Maryland to close on March 23, 2020. With the current COVID-19 pandemic front and center, I decided to browse to my local NBC news website to check out the details.

maryland-orders-coronavirus-diagnoses

Anomalies in COVID-19 State of Maryland Table

As I was reading through the article, I found the table where they provided the number of known COVID-19 cases and deaths per county quite interesting. It provided useful information that was easy to follow. However, there was an odd null entry in one of the table cells:

covid-19-cases

I immediately thought this was a little strange. software engineer mindset, and I sought to debug it to see if I could identify the details to led me to a fix (or at least a valid number). I dug a little deeper by opening the Chrome developer tools and inspected the HTML page element for the corresponding table:

<p>Hogan has already urged residents to stay home and socially distance themselves to protect from thespread of disease.</p><iframe id="myconmd" src="https://****************.html" width="100%" height="600"frameborder="0"></iframe><h2 class="wp-block-nbc-section-heading">"Unprecedented Actions" to Fight Coronavirus</h2>

The inspector details led me to an iframe that referenced another document. This reference was to an different HTML page:

<script type="text/javascript" src="js/miso.ds.deps.min.0.4.1.js"></script><script>    var tabNums = [12];    var tabNames = ["MD"];    var lang = "eng";</script><script src="*******************.js"></script>

Tracking the Source Vulnerability

After inspecting this document, I noticed yet another JavaScript file that was referenced as part of the HTML page. Surely this JavaScript was what was loading the information to create the table:

function loadData(which) {//LOAD DATA WITH MISO    ds = new Miso.Dataset({        importer : Miso.Dataset.Importers.GoogleSpreadsheet,        parser : Miso.Dataset.Parsers.GoogleSpreadsheet,        key : "*******************************", //CHANGE TO YOUR KEY HERE        worksheet : which    });    ds.fetch({        success : function() {//console.log("So say we all! Loading " + currentStateSp);            parseData();        },        error : function() {//console.log("What the frak?");        }    });}

But something caught my attention in this file: I noticed a reference to a Google Sheets importer class. This was very interesting, specifically the key value. All Google documents have a unique key associated with them, and I began to wonder if the Google Sheets corresponding to that key was accessible. One way to find out involved browsing to the document with that key ID, so I browsed to it:

google-sheets

Sure enough, the Google Sheets document was available, which made sense. However, in further examination of the document, I noticed that the document was “world editable.” This meant any internet user who stumbled on the same path, as I did, could edit the fields in the document at their will. I also discovered that the data was used by several NBC-owned local news networks. As you can see in the below screen shot, the properties of the file were set to world editable and also listed the owner of the document.

google-sheets-2

Assessing the Risk of the Google Sheet Vulnerability

This was concerning, as it appeared that the Google Sheet could be accessed by anyone. Obviously, the first thought was that anyone could manipulate any of the numbers to create incorrect information and a false narrative.

Yet, as a member of the Contrast Labs team, I immediately had a much different concern. In addition to modifying the numbers to misinform, a bad actor could enter and hid malicious JavaScript in a location or note cell by putting a lot of spaces between the “visible” text and the script and then formatting the columns to visually truncate the cell.

This malicious code could lead to a Stored Cross Site Scripting (XSS) attack. Stored XSS is a particularly pernicious attack that could lead to defacement of the web application, redirection of users to a look-a-like application, performing phishing attacks, and in some cases even installing malware or keyloggers on an end-users machine. The malicious JavaScript would be loaded and “honored” by the browser anytime the corresponding cell was rendered by the JavaScript used to render the HTML table:

function makeTable() { var theTableConent = "";for (var i=1; i<totalEntries; i++) {theTableConent += "<tr><td>" + allData[i][0].location + "</td><td>" + numberWithCommas(allData[i][0].cases) + "</td><td>" + numberWithCommas(allData[i][0].deaths) + "</td><td>" + allData[i][0].notes + "</td></tr>";}if (lang =="esp") {$("#theTable" + currentStateSp).html("<table class='table table-striped table-sm'><thead><tr><th>Ubicación</th><th>Casos</th><th>Muertes</th><th>Notas</th></tr></thead><tbody> " + theTableConent + "</tbody></table>");} else {$("#theTable" + currentStateSp).html("<table class='table table-striped table-sm'><thead><tr><th>Location</th><th>Cases</th><th>Deaths</th><th>Notes</th></tr></thead><tbody> " + theTableConent + "</tbody></table>");}$("#total" + currentStateSp).text(numberWithCommas(allData[0][0].totalcases));$("#death" + currentStateSp).text(numberWithCommas(allData[0][0].totaldeaths));$("#updated" + currentStateSp).text("Updated " + allData[0][0].updated)if (tabCount < totalTabs-1) {tabCount ++;currentStateSp = tabNames[tabCount];loadData(tabNums[tabCount]);}xtalk.signalIframe();}

Resolving the Google Sheet Vulnerability

Obviously concerned, I immediately reached out to the Data Visualization and Multimedia team at NBCUniversal Media, and they responded within minutes. The team looked into the issue immediately, and the document was locked down the same day. Kudos to NBC for acting quickly to resolve the issue! this vulnerability.

data-visualization

google-sheets-permission

 

*** This is a Security Bloggers Network syndicated blog from Security Influencers Blog authored by Mitch Ly, Sr. Software Engineer. Read the original post at: https://www.contrastsecurity.com/security-influencers/google-sheets-stored-xss-vulnerability-covid-19-table