Google Calendar was vulnerable to a series of CSRF vulnerabilities. In two separate instances, I found that existing countermeasures (CSRF tokens) were not being validated by the application.
In the first instance, I found it was possible to add an arbitrary event to a user’s calendar. I used Google Calendar’s “quick add” feature: it allows users to click on a space on the calendar and type in the name of an event, which adds it to the calendar. By monitoring the HTTP traffic between my browser and Google, I determined that the calendar entry was being created by a GET request that looked something like this (I’ve broken up the URL for the sake of readability):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
http://www.google.com/calendar/event? dates=20101103T003000%2F20101103T013000 &text=asfsaf &pprop=HowCreated%3ADRAG &src=kmVhbF9wb29sLUBicm93bi5lZGU &ctz=America%2FNew_York &eid=1288669371381 &sf=true &action=CREATE &output=js &lef=LHZkMjYxNDNmODNlOTBlbnZqMTQ0amh1Ym9AZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ &lef=MW4udXNhI2hvbGlkYXlAZ3JvdXVudi5jYWxlbmRhci5nb29nbGUuY29t &lef=bsVhbF9wb21sZUBicm92bi5lZHU &droi=20101024T000000%2F20101212T000000 &secid=-_1FyItA6aDLfYZl6GhuK62s74o
The first thing I tried doing was removing the secid parameter (which I assumed to be a CSRF token): surprisingly, while the output of the response changed slightly, it still created a new event on the calendar. I then experimented through trial and error with removing more parameters until I got the URL down to the following:
1 2 3 4 5
http://www.google.com/calendar/event? dates=20101103T003000%2F20101103T013000 &text=asfsaf &sf=true &action=CREATE
An attacker could have provided that URL to a target in any number of ways: just visiting it would have added a corresponding entry to the target’s calendar.
The second instance involved changing the privacy settings of an existing calendar. To do so, an attacker first needed to determine the calendar’s unique identifier. I proposed the following method for finding such an identifier, assuming the target is a Gmail user (and we’re interested in their default, personal calendar):
- Identify the target. Lets say the target is email@example.com.
- Register a Gmail account where the first letter of the account is different from the target’s. So, here, I might register firstname.lastname@example.org
- Sign in to Google Calendar as the attacker, take a look at the printable image version of your calendar. It will have the attacker’s email address in the upper left hand corner. The URL for the image looks something like this (I’ve omitted unnecessary parameters): https://www.google.com/calendar/printable?src=[SOME STR]&psdec=true&pft=png
- Through trial and error, try different permutations of letters/numbers in the first few characters of the src parameter. You can see how your changes affect the decoded string by looking in the upper left of the image: it will display a new email address based on your changes (sometimes it might tell you that the src is invalid, in which case you just continue trying). There’s a small enough number of possibilities that it can be brute-forced.
- Eventually, you figure out what the right src value is for the target: the email on top will match the target’s email address.
From there, the rest was simple. Privacy settings are controlled by sending a POST request to https://www.google.com/calendar/editcaldetails. A CSRF token was included if the request was made via the web interface, but omitting the token did not prevent the request from functioning. The POST body consisted of just the following:
1 2 3
dtid=[VALID-SRC] &ap=X19wdWJsaWNfcHJpbmNpcGFsX19dcHVibGljxmNhbGVuZGFyLmdvb2dsZS5jb20 &ap=20
where [VALID-SRC] was the valid src found in step 5 and the rest was a constant derived from the HTML for the corresponding form in the web interface.
The vulnerabilities mentioned here have all been confirmed patched by the Google Security Team.
To see more posts I’ve written about vulnerabilities reported under Google’s Vulnerability Reward Program, please click here.