[whatwg] DND: proposal to expose origin
Anne van Kesteren
annevk at opera.com
Fri Feb 17 01:35:28 PST 2012
The feedback that follows is based on our implementation experience with
drag & drop. The people that ought to be credited for the text below are
Paweł Stanek, Giorgi Chavchanidze, Wilhelm Joys Andersen, and anonymous;
i.e. not me.
This is a proposal for what we see as one of the most significant
limitations of HTML5 drag and drop.
The current drag and drop API has no way to restrict what documents may
become drop targets, and has no way for a drop target to know what
document was the source of the drag. This is intended to allow drag and
drop to operate freely between documents, between origins, and between
host applications. However, this has the effect of preventing sites from
safely using drag and drop for any potentially sensitive actions, such as
manipulating the contents of an address book, or initiating financial
transfers.
Imagine your bank site wants to use this API, to allow you to drag a
"payment", to a "recipient". Drop it, and they start transferring the
money. But the API does not provide any way for your bank site to be sure
that you started that drag operation on their page. For example, evilsite
puts banksite in an invisible iframe or obscured popup (clickjacking
protection is not going to help), convinces you to drag an element from
evilsite onto the iframe, dropping it on the "recipient" - a transfer is
started.
So your bank can include a password/id token in the transfer data, and
refuse to work if that does not exist. But that then opens the reverse
hole. If evilsite convinces you to start a drag operation over a banksite
"payment", and end over evilsite, evilsite will be handed the token, which
it can then use. (Remember that this is supposed to allow drag/drop
between pages that may trust each other, even if they are not same-origin,
or if they cannot access each other through the frames hierarchy. Storing
variables on the page would not be sufficient for these cases.)
Our proposal takes its cues and algorithms from the postMessage API, and
allows the source site to restrict drop targets to only those origins
which it trusts, and allows drop targets to see which origin was the
source of a drag. The majority of the algorithm can be copied from
postMessage, including the syntax for allowed target origins.
interface DataTransfer {
...
readonly attribute DOMString origin;
void allowTargetOrigin(DOMString targetOrigin);
};
Names are chosen to be compatible with those used by HTML5 Web Messaging.
dataTransfer.origin
Returns a DOMString consisting of the protocol, domain and optional
port, of
the origin where the drag started:
http://evilsite.com
http://evilsite.com:8080
If the drag was not started on an origin (such as a dragged file from the
desktop), or on a URL that is not a scheme/host/port tuple, the value
should
be the string value "null". This conforms with HTML5 subsection "Unicode
serialization of an origin" -
http://dev.w3.org/html5/spec/origin-0.html#unicode-serialization-of-an-origin
Attempts to write to dataTransfer.origin will be ignored but not throw an
error, in accordance with WebIDL.
dataTransfer.allowTargetOrigin(targetOrigin)
Defines an origin match for sites which may receive the dropped data. If
this
method is not called, then all sites and applications may be considered
dropzones.
If the value of the targetOrigin argument is neither a single U+002A
ASTERISK
character (*), a single U+002F SOLIDUS character (/), nor an absolute
URL,
then it throws a SyntaxError exception. (This is equivalent to the
algorithm
used by HTML5 Web Messaging.)
http://banksite.com
http://banksite.com:8080
* (this matches all origins, and allows exporting from the application -
equivalent to never calling allowTargetOrigin)
/ (this matches the current script origin)
file://localhost/ (this should never match any origins because file:
scheme
does not support port numbers)
If allowTargetOrigin is called when the data store is not in read/write
mode,
it must throw a SecurityError exception.
allowTargetOrigin may be called multiple times while the data store is in
read/write mode, and the effect is cumulative - a target only needs to
match
one of the targetOrigins that are supplied.
If the list of permitted origins contains at least one item, and none of
the
items is a single U+002A ASTERISK character (*), then it is not possible
to
drop items outside of the application - no data is exported.
Before firing the dragenter, dragover, dragleave and drop events, an extra
step is required which tests if the target's origin matches at least one
of the permitted targetOrigins associated with that data store, if any. If
it does not match any of them, then the event firing steps should be
aborted, and the event should not be fired. (This avoids possibly leaking
data through properties of the dataTransfer that could be seen by those
events.) The steps for the dragstart, drag and dragend events remain
unchanged, as these fire at the source node, and therefore do not need to
be affected by targetOrigin.
This does make it possible for a script to make it impossible to drop
items on its own document. This is expected and intentional.
Our (currently internal) initial implementation of drag and drop also
implements this proposal.
--
Anne van Kesteren
http://annevankesteren.nl/
More information about the whatwg
mailing list