Firefox3.1/HTML5 drag drop Security Review
Contents
Overview
This feature implements the HTML5 drag and drop api, which allows drag and drop between element on the same page, different pages, or applications.
- Background links
- [356295] - [specification]
Security and Privacy
- Is this feature a security feature? If it is, what security issues is it intended to resolve?
No.
- What potential security issues in your feature have you already considered and addressed?
Dragging between different pages or applications could potentially allow data to leak onto another site. This is prevented by not allowing access to data added from a different source until the drop occurs.
- Is system or subsystem security compromised in any way if your project's configuration files / prefs are corrupt or missing?
No configuration files or preferences are used.
- Include a thorough description of the security assumptions, capabilities and any potential risks (possible attack points) being introduced by your project.
A drag operation begins when a user drags the mouse on a page or window. This results in a dragstart event firing on the target. Drag and drop operations may not be simulated by script. That is, dispatching drag events manually cannot cause a real drag to occur.
Data may be added by script during a dragstart event to a data transfer object, which holds the data to be dragged. Data consists of a type name (a mime like string such as text/plain) and a data value. Data is stored along with the principal of the caller that set the data. Only chrome callers may add data of the application/x-moz-file type, which is used for files.
Some extension APIs (prefixed with moz) are used to allow multiple items to be dragged as well as non-string data, which are needed for compatibility with existing code.
During the drag, various events such as dragenter, dragover, etc are fired on the elements being dragged over. The spec doesn't allow retrieval of the data during this time, but we allow access as long as the caller's principal matches. The types that the data transfer holds are always accessible however.
Data is accessible only when the user performs the drop operation.
There are various concerns here, and am wondering now if some aspects should be disabled or prevented for now:
- what if, for example, a user accidentally drags a bookmark or some other UI onto a page?
- I realize now upon reviewing that I'm relying on XPConnect privileges to prevent access to dropped files or other objects. Perhaps a drop should prevent this?
- even assuming only string data, a dragged file can result a data type of 'text/plain' where the data is the filename.
- the drag and drop API makes no real assumptions about what kind of data particular types should contain. As custom types may be used, it could be possible for a caller to place unexpected data to be dragged.
- existing browser chrome code has a check in place when receiving links to ensure that the originator (the target of dragstart) of the drag can access that link. This prevents a site from tricking the user into dragging a chrome url. But other code may not check for this.
- How are transitions in/out of Private Browsing mode handled?
Haven't considered it yet, don't think there is an issue.
Exported APIs
- Please provide a table of exported interfaces (APIs, ABIs, protocols, UI, etc.)
Adds interfaces: nsIDOMDragEvent, nsIDOMDataTransfer, and also adds new drag related event types
- Does it interoperate with a web service? How will it do so?
No
- Explain the significant file formats, names, syntax, and semantics.
No files are used.
- Are the externally visible interfaces documented clearly enough for a non-Mozilla developer to use them successfully?
Yes, in the specification and at http://developer.mozilla.org/En/DragDrop/Drag_and_Drop
- Does it change any existing interfaces?
It changes nsIDragService to support the data transfer object which holds the data to be dragged. It is expected that nsIDragService will no longer be used by chrome code directly, except for dragging in XUL trees which still uses this API.
Module interactions
- What other modules are used (REQUIRES in the makefile, interfaces)?
Changes are made mostly to content/events, but also to dom and widget.
Data
- What data is read or parsed by this feature?
Data may be added by script during a dragstart event to a data transfer object, which may be retreived at the end of the drag.
- What is the output of this feature?
Data dropped can result in something being copied or moved to a new location.
- What storage formats are used?
None
Reliability
- What failure modes or decision points are presented to the user?
None
- Can its files be corrupted by failures? Does it clean up any locks/files after crashes?
No new files are saved. I think the existing underlying drag code can save a temporary file holding the data being dragged if it is very large, but that code hasn't been modified.
Configuration
- Can the end user configure settings, via a UI or about:config? Hidden prefs? Environment variables?
No configuration is possible.
- Are there build options for developers? [#ifdefs, ac_add_options, etc.]
No
- What ranges for the tunable are appropriate? How are they determined?
Not sure what this means, so I'll say no.
- What are its on-going maintenance requirements (e.g. Web links, perishable data files)?
Relationships to other projects
Are there related projects in the community?
- If so, what is the proposal's relationship to their work? Do you depend on others' work, or vice-versa?
No
- Are you updating, copying or changing functional areas maintained by other groups? How are you coordinating and communicating with them? Do they "approve" of what you propose?
No
Review comments
Here is an example of [dnd]
- If you drag a desktop image onto or over a page, what data can the page see? Don't want to leak the image data or the full file path. Filename is probably OK.
- seems like if you drop a bookmark or desktop file onto a page the page now can get information about it that it couldn't before, while the user simply thinks they're navigating somewhere.
- setData() adds things in named formats. can't getData(fmt) or clearData(fmt) if that format was added by a different domain.
- setDragImage() is limited to adding images up to half the size of the original. transparency is added by us.
- can only add set the image or add data during the dragStart event
- web pages can't add data with the type given to files. There are probably a lot of other types we need to disallow, any that the browser itself relies on. e.g. when dragging a link to the bookmark toolbar, we don't want the page to be able to add data that might add extra bookmark meta-data like tags or keywords.
- getData() does NOT check principals during the drop event. the target does need to get the data, but more than the default data?
- supported formats: https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types