[whatwg] a rel=attachment

Darin Fisher darin at chromium.org
Fri Jul 15 14:34:29 PDT 2011

On Fri, Jul 15, 2011 at 1:09 PM, Jonas Sicking <jonas at sicking.cc> wrote:

> 2011/7/15 Ian Fette (イアンフェッティ) <ifette at google.com>:
> > 2011/7/15 Jonas Sicking <jonas at sicking.cc>
> >
> >> 2011/7/14 Ian Fette (イアンフェッティ) <ifette at google.com>:
> >> > Many websites wish to offer a file for download, even though it could
> >> > potentially be viewed inline (take images, PDFs, or word documents as
> an
> >> > example). Traditionally the only way to achieve this is to set a
> >> > content-disposition header. *However, sometimes it is not possible for
> >> the
> >> > page author to have control over the response headers sent by the
> >> > server.*(A related example is offline apps, which may wish to provide
> >> > the user with
> >> > a way to "download" a file stored locally using the filesystem API but
> >> again
> >> > can't set any headers.) It would be nice to provide the page author
> with
> >> a
> >> > client side mechanism to trigger a download.
> >> >
> >> > After mulling this over with some application developers who are
> trying
> >> to
> >> > use this functionality, it seems like adding a "rel" attribute to the
> <a>
> >> > tag would be a straightforward, minimally invasive way to address this
> >> use
> >> > case. <a rel=attachment href=blah.pdf> would indicate that the browser
> >> > should treat this link as if the response came with a
> >> content-disposition:
> >> > attachment header, and offer to download/save the file for the user.
> >>
> >> We've discussed a different solution to the same problem at mozilla.
> >> The solution we discussed was allowing FileSaver to in addition to
> >> taking a blob argument, allow it to take a url argument.
> >>
> >> One concern which was brought up was the ability to cause the user to
> >> download a file from a third party site. I.e. this would allow
> >> evil.com to trick the user into downloading an email from the users
> >> webmail, or download a page from their bank which contains all their
> >> banking information. It might be easier to then trick the user into
> >> re-uploading the saved file to evil.com since from a user's
> >> perspective, it looked like the file came from evil.com
> >>
> >> Another possible attack goes something like:
> >> 1. evil.com tricks the user into downloading sensitive data from
> bank.com
> >> 2. evil.com then asks the user to download a html from evil.com and
> >> open the newly downloaded file
> >> 3. the html file contains script which reads the contents from the
> >> file downloaded from bank.com and sends it back to evil.com
> >>
> >> Step 1 and 2 require the user to answer "yes" to a dialog displayed by
> >> the browser. However it's well known that users very often hit
> >> whichever button they suspect will make the dialog go away, rather
> >> than actually read the contents of the dialog.
> >> Step 3 again requires the user to answer "yes" to a dialog displayed
> >> by the browser in at least some browsers. Same caveat applies though.
> >>
> >> One very simple remedy to this would be to require CORS opt-in for
> >> cross-site downloads. For same-site downloads no special opt-in would
> >> be required of course.
> >>
> >> It's also possible that it would be ok to do this without any opt-ins
> >> since there are a good number of actions that the user has to take in
> >> all these scenarios. Definitely something that I'd be ok with
> >> discussing with our security team.
> >>
> >> Tentatively I would feel safer with the CORS option though. And again,
> >> for same-site downloads this isn't a problem at all, but I suspect
> >> that in many cases the file to be downloaded is hosted on a separate
> >> server.
> >>
> >> Oh, and I don't have strong opinions at this time on if rel=attachment
> >> or FileSaver or both should be the way to trigger this functionality.
> >>
> >> / Jonas
> >>
> >
> > I agree FileSaver is useful and has its place, but I don't think it
> negates
> > the need for something like rel=attachment or download=filename. For one,
> > FileSaver currently operates on blobs and as you mention would have to be
> > modified to handle URLs or streams more generally. Second, it would force
> > developers to use javascript links and/or set up click listeners and so
> > forth, which could be annoying for users (losing the ability to copy the
> > etc).
> As stated, I don't have a strong preference here. I suspect ultimately
> we'll end up wanting both a markup based and an API based solution
> here.
> > I guess the interesting question is "If the response would not have
> > otherwise triggered a download, and the request is cross-origin, should
> that
> > require CORS" and personally I would say no, this is still a remote
> enough
> > concern that I would not worry about it.
> Indeed, that is the interesting question.
> I know that I would personally feel a lot more comfortable if the site
> opted in to allowing downloads of the resource in question. But it's
> quite possible that I'm overly paranoid.
> Though one thing to keep in mind is sites that explicitly state that a
> resource should *not* reach the users disk. This is today often done
> using "Cache-Control: no-store". Seems scary to allow such content to
> be saved based on a cross-site request.
> / Jonas

This security concern is very interesting.  I had not considered it before.

Putting that aside for a moment, I'm glad to hear that you also support
there being some declarative method of triggering a download.  Which of
the proposals are you leaning toward?

Personally, I'm most fond of the @download=filename method.  Reason:

1)  Unlike rel=something, @download is feature detectable at runtime via
("download" in document.createElement("a")).

2)  Unlike rel=something, @download provides a way to specify the name
of the file to save.  This makes the feature useful with data: URLs and
URLs (that are not backed by a single file).  This is valuable to me because
I can imagine wanting to save the contents of a <canvas>, and that probably
involves saving the data URL that you get from toDataURL().

3)  The target=_download idea is interesting, but I'm not sure we can safely
introduce new target values, and this also suffers from not providing a way
specify the downloaded filename.

4)  The idea of using both a rel=something and an attribute to specify the
name could work too, but it seems a bit overly verbose.  I'm not sure I see
enough benefit from this.  The idea of providing a name for <img> tags that
might be downloaded manually by the user is interesting, but it feels like a
far less interesting problem to solve.  If our solution solves this too,
then great,
but I wouldn't necessarily make it a requirement to solve this problem too.

Anyways, what do you think?  I'd really like to reach some consensus on what
the declarative method should look like.

Whatever security restrictions we come up with will need to apply to
too assuming FileSaver ends up taking an URL (and a filename!).


More information about the whatwg mailing list