[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