Advisory: Open Redirect on


A marketing server at operated an open redirect.


Google’s main AdWords landing page takes a cd parameter indicating a specific country to target, which redirects to a country-specific page. Examples of such URL are as follows:



The cd parameter which specifies the country was not checked against a valid list of values. Instead, this parameter is used to replace the “com” value in the URL with the value from the cd parameter. For example:


This can be used to redirect users to a malicious page. Example URL with malicious content:

Redirects to:

The vendor communicated that they consider this a low level attack, and do not plan to track a fix for this issue. However, we have since confirmed that this issue has been fixed prior to publication.


Google Security CID: 9–6197000008153
Google’s view on open directs:


Discovered and written by Yakov Shafranovich


2015–08–07: Vendor notified
2015–08–07: Initial vendor response
2015–08–11: Vendor replicated the issue
2015–09–05: Follow up communications with vendor
2015–09–20: Fix confirmed
2015–10–12: Public disclosure

2016–03–14: Updated disclosure posted

Advisory: Content Injection in Google Calendar API (Google)


Google Calendar embedding API allows injection of arbitrary content.


Google Calendar offers an embedding API, allowing calendars to be embedded in web pages. This API is accessible at the following URL:<url>


In case of an invalid URL, it mirrors back the text of the URL. For example, the following URL:<url>

would show the following message:

Invalid calendar id: <url>

While we have not been able to show script execution, we believe that this can still be used as a vector of attack, especially since this injects content into a page that is SSL secured with a Google certificate. Interestingly, a similar content injection attack was considered to be severe enough by Microsoft to be fixed (as per our earlier blog post).

We would like to present the following attack scenarios:

Scenario #1 — Phishing attack

An attacker can use this to send email to Google Calendar users with the following URL:

Resulting in the following message:

Invalid calendar id: -We are having a problem with your account. Please call 1–800-BAD-GUYS x123 and give them your password

A sophisticated attack can issue a unique extension for each spammed address, bypassing the requirement for users to provide their email address over the phone. It would also be possible to automate such attack with voice API providers like Twilio, further making users feel at ease, since most phone phishing attempts use humans.

Scenario #2 — Stock manipulation attack

An attacker can use the following URL to show a fake Google Calendar in attempt to manipulate the stock market:

This would result in the following message:

Invalid calendar id: -BEGIN:VEVENT SUMMARY: UID:12345 DESCRIPTION;Sergey Brin/Elon Musk to announce $GOOG acquisition of $TSLA LOCATION:Mountainview, CA DTSTART;TZID=/US/Eastern:20151109T100000 DTEND;TZID=/US/Eastern:20151109T113000 URL: END:VEVENT

Seemingly this would indicate a fake calendar event announcing the acquisition of Tesla Motors by Google. HOWEVER, given that the embed API can be used to embed any calendar, it would be trivial to create a real Google calendar with fake info and embed it.


(Please note the SSL icon)


Vendor Response

Vendor response is as follows:

There is no XSS demonstrated here, just content injection, which has legitimate use and is not a technical security bug for the purposes of our reporting program (phishing generally isn’t a “technical” enough attack scenario). All inputs appear to be properly sanitized, so if you want to demonstrate an actual XSS, you’d need to show proof of script execution


Google Security CID: 6–1050000008145
Google Calendar Embed docs:


2015–08–07: Vendor notified
2015–08–07: Vendor response
2015–10–26: Public disclosure

Version Information

Version 1
Last updated on 2015–09–21

Research: Chrome For Android Reveals Phone Model and Build

[UPDATED: 2018-12-25 – we published an expanded post with fix information]


Google’s Chrome browser for Android tends to disclose information that can be used to identify the hardware of the device it is running on. This problem is further exacerbated by the fact that many applications on Android use Chrome WebView or Chrome Custom Tabs to render web content.

Background — Chrome and Headers

The Chrome browser for Android is provided by Google as the build-in browser in the Android operating system for mobile devices. It is based on the Chromium open source project. It also provides the WebView and Custom Tabs APIs for other applications running on the Android platform, to be used for rendering web content within the apps themselves without opening a separate browser window.

As all browsers, Chrome sends a variety of headers as part of every request to the web servers it communicates with. These headers are defined in the HTTP protocol, latest standard of which can be found in RFCs 7230, 7231, 7232, 7233, 7234 and 7235. Among these is the User-Agent header which is the subject of this post.

The “User-Agent” header in HTTP is defined by RFC 7231, section 5.5.3 as follows:

The “User-Agent” header field contains information about the user agent originating the request, which is often used by servers to help identify the scope of reported interoperability problems, to work around or tailor responses to avoid particular user agent limitations, and for analytics regarding browser or operating system use.

Background — Android Model and Build ID

Android devices have a build-in MODEL and BUILD ID, identifying the phone model and Android build. They are defined in in android.os.Build.MODEL and android.os.Build.ID properties. These are further defined in the Android Compatibility Definition document (section 3.2.2) as follows:

MODEL — A value chosen by the device implementer containing the name of the device as known to the end user. This SHOULD be the same name under which the device is marketed and sold to end users. There are no requirements on the specific form

ID — An identifier chosen by the device implementer to refer to a specific release, in human-readable format. This field can be the same as android.os.Build.VERSION.INCREMENTAL, but SHOULD be a value sufficiently meaningful for end users to distinguish between software builds. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^[a-zA-Z0–9._-]+$”.

An attempt to map models to more descriptive names can be found on GitHub. A list of known build IDs for Nexus devices can be found here and here.


As per Chrome docs, the Chrome for Android User Agent string includes the Android version number and build tag information. This information by default is also sent when applications use Android’s WebView and Chrome Custom Tabs APIs to serve web content in their own applications. While Android does offer ability to override these (via WebSettings.setUserAgent() in WebView), most applications choose not to do that to assure compatibility by relying on the default header.

Aggravating this issue is that the user agent header is sent always, with both HTTP and HTTPS requests, often by processes running in background. Also, unlike the desktop Chrome, on Android no extensions or overrides are possible to change the header other than the “Request Desktop Site” option on the browser itself for the current session.

For example of a user-agent header for Chrome Beta, on Nexus 6, with Android v5.1.1:

Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.34 Mobile Safari/537.36

When a user chooses the “Request Desktop Site” option, the user agent header sent is a generic Linux header instead. Here is an example for Chrome Beta, on Nexus 6, with Android v5.1.1:

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.34 Safari/537.36

The difference is that on mobile mode, the following string is extra:

Android 5.1.1; Nexus 6 Build/LYZ28K

The fact that it identifies the operating system and its version is not unique. This follows generally what many other browsers have been doing on desktop and mobile. It is the build tag that is the problem. As described above, the build tag identifies both the device name and its firmware build. For many devices, this can be used to identify not only the device itself, but also the carrier on which it is running and from that the country.

An example can be easily seen from the above where build LYZ28K can be easily identified as Nexus 6 running on T-Mobile, implying a US presence. It would also be trivial to use the build information to figure out the carrier based on which carriers are known to be at what build number. Build numbers are easily obtainable from manufacturer and phone carrier websites

Bug # 494452 has been filed for this against Chromium before, but Google has choose to keep the design of the user agent string intact.

Possible Mitigation by Android Applications Using WebView

As discussed above, application authors can use WebSettings.setUserAgent() method to set the override the user agent. While many are reluctant to do so in order to lose compatibility, we would like to suggest the following approach of using the default user agent and erasing the build information in it.


Even the NSA described that user agents only identify browsers. Unfortunately, on Android they can also identify the device model, carrier and more. In our opinion, this is simply too much information as it reveals the underlying firmware. While user fingerprinting exists, it is less trivial to tie a specific piece of software to a specific piece of hardware with the granularity of carrier, build and country. An analogy to this would be a desktop browser sending the vendor name and the build number of the BIOS in a desktop computer. Additionally, this information can be used to target users with malware attacks targeting specific builds known to be vulnerable.

We suggest following the approach taken by Mozilla:

Adding a device identifier to the Firefox OS User Agent (UA) string is STRONGLY DISCOURAGED by Mozilla.


Mozilla strives to provide greater privacy for users. Therefore, we have been working to reduce the level of “fingerprintability” of different browser configurations — that is to say, how uniquely identifiable a particular user’s browser is to sites through detection methods of which the user is unaware. (i.e. server-side methods) Adding e.g. hardware information to the UA reduces privacy by increasing fingerprintability.


Researched and written by Yakov Shafranovich.