Such examples give a false sense of simplicity. In the
real world, the source of messages could be one of
many possible fine grained origins and possibly differing
schemas. As a result, validating the origin becomes non-
trivial. Additionally, for complex protocols, these checks
must be repeated for every message—a tedious exercise
which can be easily forgotten. In fact, in our discussion
with Facebook, we were informed that they used the
all-permissive ‘*’ directive because
postMessage
does
not support multicast and implementing this function-
ality would require a series of string-based verification
comparisons—which is precisely the problem we have
outlined above. Furthermore, if a mashup includes content
from more than a couple of origins, these checks become
even more taxing. Fundamentally, this is a usability issue of
the API. In Section IV, we suggest potential enhancements
to the specifications to mitigate these issues, in keeping
with the economy of liabilities principle.
The use of the all-permissive ‘*’ as the
targetOrigin
allows leakage of confidential data. The HTML5 speci-
fication [15] warns against the use of the ‘*’ literal for
confidential data. We believe giving developers the choice
of insecure usage is not a good practice. Additionally,
it is notoriously hard to figure out what data is privacy
sensitive and what isn’t [9]—and we believe this will only
get more difficult. Based on these facts, we suggest a
possible modification in Section IV.
III. PERSISTENT, SERVER-OBLIVIOUS CLIENT-SIDE
DATABASE ATTACKS
In this section, we study the usage of new client side
persistent storage mechanisms supported by HTML5 and
Google Gears. We find that data stored in client-side
databases is often used in code evaluation constructs
without sanitization. Client-side databases, thus, provide
additional avenues for attackers to persist their payloads
across sessions. For instance, attackers only need to inject
XSS attack payloads once into the client-side storage to
have them repeatedly compromise the client-side code
integrity for sustained periods of time (unlike a common
reflected XSS issue which is fixed once patched). Addition-
ally, because the attack payload is stored on the client-side,
the server is oblivious to the nefarious activity. We show
that the 7 out of 11 major applications we studied trust the
client-side storage and are vulnerable to such persistent
attacks, including: Gmail, Google Buzz, Google Documents
and others.
A. Client-side Storage: Background
HTML5 proposes two persistent storage abstractions:
localStorage
and
webDatabase
[16], [17]. A limited
number of browsers currently support these features. The
client-side storage mechanisms work as follows:
• localStorage
is a key/value store tied to an ap-
plication’s origin. Script executing within an origin
can get or set values of the data store using the
localStorage object.
• webDatabase
is a client-side database that supports
execution of SQL statements. The database is bound
to the origin in which the code executes and web
applications are restricted to only modifying the
structure and contents of their associated origin’s
database. To execute SQL against the database one
can use:
executeSql(sqlStatement, arguments,
callback, errorCallback).
•
Gears is a Google product designed to enable ap-
plications to work offline. Recently, Google has
decided to deprecate Gears in favor of HTML5 [4].
Despite syntactic differences, Gears and HTML5
webDatabase
data storage work in very similar ways.
In each of these cases, database modifications persist
until the creating application destroys the data.
B. Persisting Server-Oblivious Attack Payloads
We consider two possible attack vectors in our threat
model, a network attacker and a transient XSS vulnerability.
The goal of either attacker is to inject code into the
local storage in order to gain a persistent foothold in the
application—one that remains even when the transient
attack vector is fixed. Once an application has been compro-
mised, the attacker has control of the application until the
client side database is cleared. In current implementations,
this only occurs when the database is explicitly cleared by
an application, making the attack have a long lifetime.
Network Attacker.
Consider the case when a network
attacker is able to modify packets destined to the victim.
When the user visits a site using client-side storage the
attacker modifies the victims network packets to allow the
network attacker to inject arbitrary JavaScript. This allows
the attacker to compromise the database with no trace
server-side that a client-side exploit has occurred until the
client-side database is cleared.
As an example of a realistic scenario, consider when a
user visits a coffee shop with open wireless. Unbeknownst
to him, the network attacker intercepts his network con-
nections so that they are forwarded through the attacker’s
computer. When the user visits Google Buzz, the network
attacker modifies the page returned to supply a script which
modifies the client-side database. Now, whenever the data
from the database is used in a code evaluation construct, the
attack payload is executed instead. The user now leaves the
cafe with a compromised machine and due to the stealthy
injection (with no server side XSS required), little evidence
remains that an attack occurred.
Transient XSS.
As a second attack vector, suppose that
an attacker has exploited a transient XSS vulnerability
as a primary attack vector and has been able to execute
arbitrary code within the context of the target site. The
attacker is able to modify the database arbitrarily because
the attacker has used the XSS to execute JavaScript with
the same privilege as the code running within that origin.
Not only is this attack persistent, it is also stealthy. Besides
the initial XSS injection vector, all of the code execution
and state modification happens on the client-side rendering
the server oblivious to the attack.
For a concrete example, suppose an attacker finds
an XSS attack on a web email application that uses