Tag: google
2010
12.07

Summary

Google Scholar was vulnerable to minor but potentially annoying CSRF vulnerabilities in two different pages. The regular search equivalents of both of these pages used CSRF tokens to mitigate these problems.

Vulnerability #1

There was no CSRF protection used when saving preferences in Google Scholar. So, browsing to the following URL used to set your language on Google Scholars to Arabic and set your search results to return papers written in Chinese: http://scholar.google.com/scholar_setprefs?hl=ar&lang=some&lr=lang_zh-CN&submit. As of right now, the URL no longer updates user preferences (although it does change the language for the current page, and any page accessed from links/forms off of that page).

Vulnerability #2

There was no CSRF check in place for setting up email alerts in Google Scholar. A simple POST to http://scholar.google.com/scholar_alerts?view_op=list_alerts&hl=en where the POST data was

1
2
3
alert_query=[SOME QUERY]&
alert_max_results=10&
create_alert_btn=Create+alert

would have resulted in an alert being created for the currently logged in user (there was a parameter, email_for_op, that was passed in during a real request: removing it seemed to cause the system to default to the currently logged in user’s email address).

More Information

The vulnerabilities mentioned here have all been confirmed patched by the Google Security Team. I owe them a ton of thanks for organizing this program and giving me a chance to improve my skills. :-)

To see more posts I’ve written about vulnerabilities reported under Google’s Vulnerability Reward Program, please click here.

2010
11.30

Summary

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.

Walkthroughs

Example #1

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.

Example #2

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):

  1. Identify the target. Lets say the target is example@gmail.com.
  2. Register a Gmail account where the first letter of the account is different from the target’s. So, here, I might register fxample@gmail.com
  3. 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
  4. 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.
  5. 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.

More Information

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.

2010
11.30

When a friend of mine told me about Google’s new vulnerability reward program for web applications, my first reaction was a mix of excitement and skepticism. On the one hand, I love web application security and penetration testing: this program was right up my alley (especially given my recent abundance of free time). On the other hand, I had never run across a security vulnerability in a Google application before: I wasn’t sure that I would find anything, even if I looked hard.

As it turned out, I needn’t have worried: I spent many hours testing various Google webapps, but I also found plenty of vulnerabilities. ;-)

Under the terms of the program (and the rules of responsible disclosure), I will not be discussing the details of any vulnerabilities until they are fully resolved. Once the Google Security Team has confirmed to me that a particular issue has been dealt with, I will be doing a little writeup about it on this blog (a full list of the writeups can be found here). Hopefully people will find the writeups informative. :-)

2010
11.14

I spent quite a bit of time last night configuring Pidgin, my new IM client. A large portion of that time was focused on one particular issue: getting a Google Talk account (when using Google Apps for Your Domain) to play nicely with Pidgin. From looking at the search results for “google talk pidgin”, it looks like I’m not the only one with that problem. Since I did eventually get everything set up, I decided to document the process here in the hopes it might help someone else. :-)

The first thing I did was check out Google’s official documentation (http://www.google.com/support/a/bin/answer.py?hl=en&answer=49147). I followed the instructions, but when I went to connect I encountered a variety of error messages. “Read error”, “Unable to connect”, “Server closed the connection”, etc. The documentation was clearly missing a step.

Next, I stumbled on some references in the Google Talk help forum to a post on the Ubuntu forums (http://ubuntuforums.org/showthread.php?t=499906). The post talks about changing some advanced configuration settings for the account. After a little bit of trial and error with the settings, I found a combination that works.

How to configure the account

You’ll want to load the “Modify Account” screen (assuming the account is already created). That can be accessed by going to the Accounts menu, selecting the account in question, and choosing “Edit Account” from the list of options.

Once the screen is loaded, click on the Advanced tab. You’ll be presented with a number of different configuration options. The following list contains the settings I updated, along with what I set their values to. Any omitted settings can be left as-is.

  • Connection security: Use old-style SSL
  • Connect port: 5223 (this was the default, but it’s worth repeating here)
  • Connect server: talk.google.com

With those changes in place, Pidgin connected to Google Talk without complaint. :-)

Note: These steps were performed on Pidgin 2.7.5. If you’re using a different version of Pidgin, your steps may be slightly different, your form fields may have different names, etc.

2010
07.03

Recently at work, one of my friends ran into a problem trying to integrate the Google Visualization API and jQuery. His setup seemed fairly straightforward and it didn’t seem like there would be any problems. He wanted the user to select an option from a dropdown box. That selection would trigger a GET request to fetch some JSON (using the getJSON function of jQuery) from his web server. The result of the request would be passed via getJSON’s callback to Google Visualizations, which would then display some nice charts.

Sounds easy, right?

Unfortunately, when he tested his code in Firefox, the visualization he wanted never showed up. All he saw was an empty iFrame where his chart should have been (Google Visualizations draws certain types of charts using SVG in iFrames).

Puzzled, he started debugging. He quickly confirmed that the proper calls to draw the visualization were being made. Yet somehow, they were just returning an empty iFrame instead of one filled with data. Even more puzzling, his code worked fine when he tested it in Google Chrome, Safari, etc: Firefox was the only browser where it failed!

His next step was to try replacing his chart code with Google’s example code, thinking that maybe the issue was with his data. Amazingly, that chart also failed to display properly! However, it also led him to another discovery: the chart drawing would only fail if it was attempted from within getJSON’s callback function. If the chart was drawn before or after, it would work correctly.

Finally, after several people spent hours wrestling with the problem, one of our fellow employees came up with a solution. He created a closure that would call the correct Javascript functions to draw a graph. Then, he passed that closure to setTimeout with a timeout of 0. It was a fairly elegant workaround: using setTimeout avoided the weird scoping issue (we still don’t understand what the problem was!) and the closure allowed the data to be passed out of the troublesome callback and to the Google Visualization classes. Definitely not the cleanest solution, but very welcome after several hours of wrestling with the problem!