Reflected Cross-Site Scripting (XSS)

After learning about Google's bug bounty program, I decided to look for vulnerabilities on their most sensitive services. Finding a vulnerability on was challenging; I managed to find a simple, but interesting form of Cross-Site Scripting.



Proof of Concept:;// is a part of Google Apps service where you are able to configure permissions, users, and Google Services for your domain. This is a feature primarily used by businesses, especially ones that are using Gmail as the e-mail service for their domain.

The ServiceNotAllowed page appears when you are attempting to access a Google app service that has not been configured for your domain. It requires that you are logged into at least two accounts and will give you a form to switch accounts to continue to the service you were trying to load. When you select an account via the bullet on the page, it executes JavaScript to redirect your browser. The URL used in this JavaScript is supplied by the user in the continue request parameter.

The continue request parameter is fairly common request variable in the Google login flow. This is the only page that I could find that did not validate the URL passed into it. This allowed you to craft Cross-Site Scripting attacks by using "javascript:" as part of the URL and it would execute when the browser location is redirected.



This attack allows you to force a Google Apps admin to execute any request on the domain. Some things that are possible:

Forcing the admin to ...

  • Create new users with any permission level that you want, such as a super admin.
  • Disable security settings for individual accounts or for multiple domains. This includes removing two-factor authentication (2FA) from accounts.
  • Modifying domain settings so they point to your domain/dns, therefore all incoming emails to that domain are redirected to you instead.
  • Hijack an account/email by resetting the password, disabling 2FA, and also removing login challenges temporarily for 10 minutes.

To demonstrate this, I built a proof-of-concept that shows a JavaScript payload pulling information from the Admin console, grabbing a list of users, changing the password and removing security settings from the first user in the list.


<form action="" onsubmit="return onContinueClick(2);">
	<li><input type="radio" value="javascript:alert(document.cookie);//?authuser=0" checked name="radioChoices" id="radioid0"><label for="radio0"></label></li>
	<li><input type="radio" value="javascript:alert(document.cookie);//?authuser=0" checked name="radioChoices" id="radioid1"><label for="radio1"></label></li>

	function onContinueClick(accountCount) {
		var href;
		for (var i = 0; i < accountCount; i++) {
			if (document.getElementById('radioid' + i).checked) {
				href = document.getElementById('radioid' + i).value;
		window.location.href = href;
		return false;
	window.addEventListener("load", function() {



  • Discovered and reported: 9/1/14
  • Acknowledged: 9/5/14
  • Fixed: 9/18/14

Bounty Reward: