Last Comment Bug 676619 - Implement proposed download attribute
: Implement proposed download attribute
Status: RESOLVED FIXED
: dev-doc-complete
Product: Core
Classification: Components
Component: DOM: Core & HTML (show other bugs)
: Trunk
: All All
: -- normal with 25 votes (vote)
: mozilla20
Assigned To: Tom Schuster [:evilpie]
:
: Andrew Overholt [:overholt]
Mentors:
: 747357 784119 787941 (view as bug list)
Depends on: 940568 665216 795442 835198 874009
Blocks: html5test 819373 923415 818559
  Show dependency treegraph
 
Reported: 2011-08-04 12:07 PDT by Tom Schuster [:evilpie]
Modified: 2015-04-03 10:20 PDT (History)
57 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
wip patch (16.92 KB, patch)
2012-09-23 05:06 PDT, Tom Schuster [:evilpie]
no flags Details | Diff | Splinter Review
WIP v2 (16.00 KB, patch)
2012-09-29 06:09 PDT, Tom Schuster [:evilpie]
no flags Details | Diff | Splinter Review
WIP v3 (20.33 KB, patch)
2012-10-05 12:59 PDT, Tom Schuster [:evilpie]
no flags Details | Diff | Splinter Review
WIP v4 (34.27 KB, patch)
2012-11-03 14:39 PDT, Tom Schuster [:evilpie]
no flags Details | Diff | Splinter Review
Test WIP (4.18 KB, patch)
2012-11-17 07:43 PST, Tom Schuster [:evilpie]
no flags Details | Diff | Splinter Review
v1 (36.39 KB, patch)
2012-11-20 07:00 PST, Tom Schuster [:evilpie]
bugs: review-
Details | Diff | Splinter Review
tests v1 (6.46 KB, patch)
2012-11-20 07:04 PST, Tom Schuster [:evilpie]
bugs: review+
Details | Diff | Splinter Review
v2 (36.84 KB, patch)
2012-11-26 10:21 PST, Tom Schuster [:evilpie]
no flags Details | Diff | Splinter Review
v2.1 (35.52 KB, patch)
2012-11-26 10:41 PST, Tom Schuster [:evilpie]
bugs: review+
Details | Diff | Splinter Review
change params to nsAString (13.98 KB, patch)
2012-11-26 11:09 PST, Tom Schuster [:evilpie]
bugs: review+
Details | Diff | Splinter Review
modified test for https (3.25 KB, patch)
2012-12-06 10:31 PST, Tom Schuster [:evilpie]
bugs: review+
Details | Diff | Splinter Review

Description Tom Schuster [:evilpie] 2011-08-04 12:07:16 PDT
This is probably a dup, but chrome just implemented download="filename.txt". Which is neat, because you can specify the download name of implemented with data-uris etc.

http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-July/032489.html
http://functionsource.com/post/downloadmynameisslimshady-png
Comment 1 Olli Pettay [:smaug] 2011-08-04 12:26:27 PDT
I don't recall a bug about download attribute.
Comment 2 Olli Pettay [:smaug] 2011-08-04 13:28:25 PDT
Jonas, you've been activate in the download attribute discussion.
Do you know if the spec is sane?
Comment 3 Jonas Sicking (:sicking) No longer reading bugmail consistently 2011-08-04 14:21:47 PDT
The big problem is that it allows cross-origin downloads. Even of sensitive contents such as bank statements and such which contains sensitive account and credit card numbers.

We definitely need to do a security review before we allow that.
Comment 4 Bronislav Klučka 2011-10-08 13:21:03 PDT
(In reply to Jonas Sicking (:sicking) from comment #3)
Hi, could you be more specific about security issues? specifically how could one download bank statements?
Comment 5 Jonas Sicking (:sicking) No longer reading bugmail consistently 2011-10-10 01:50:45 PDT
insert something like the following in the page:

<a href="http://bank.com/statement.cgi" download="statement.html">

The actual URL depends on the bank of course.

When the user clicks such a link, the user will be prompted if they want to download. It seems very easy for the user to make the mistake of thinking that something on the original website is being downloaded, and not something from bank.com.
Comment 6 Bronislav Klučka 2011-10-10 03:14:00 PDT
(In reply to Jonas Sicking (:sicking) from comment #5)
> insert something like the following in the page:
> 
> <a href="http://bank.com/statement.cgi" download="statement.html">
> 
> The actual URL depends on the bank of course.
> 
> When the user clicks such a link, the user will be prompted if they want to
> download. It seems very easy for the user to make the mistake of thinking
> that something on the original website is being downloaded, and not
> something from bank.com.

I assumed something like that... but secured pages are either not vulnerable to such attack (e.g. each request must have some valid unique ID) or I can actually  do that without download attribute (but with much more programming overhead and probably with server programming as well). There is actually no security issue that does not exists today, download attribute may add easier way to fool users by attackers, but no new one... instead of programming for 1 minute to add attribute one would have to programm 30 minutes... 

since "We definitely need to do a security review before we allow that" is there any research beeing done?

Would it be possible to implement it with same-origin and CORS (Access-Control-Allow-Origin) in mind if you are questioning cross origin security? This is very useful feature for web applications (create Blob using JS and let user download it with some meaningful name)
Comment 7 Jonas Sicking (:sicking) No longer reading bugmail consistently 2011-10-10 09:41:39 PDT
(In reply to Bronislav Klučka from comment #6)
> (In reply to Jonas Sicking (:sicking) from comment #5)
> > insert something like the following in the page:
> > 
> > <a href="http://bank.com/statement.cgi" download="statement.html">
> > 
> > The actual URL depends on the bank of course.
> > 
> > When the user clicks such a link, the user will be prompted if they want to
> > download. It seems very easy for the user to make the mistake of thinking
> > that something on the original website is being downloaded, and not
> > something from bank.com.
> 
> I assumed something like that... but secured pages are either not vulnerable
> to such attack (e.g. each request must have some valid unique ID) or I can
> actually  do that without download attribute (but with much more programming
> overhead and probably with server programming as well). There is actually no
> security issue that does not exists today, download attribute may add easier
> way to fool users by attackers, but no new one... instead of programming for
> 1 minute to add attribute one would have to programm 30 minutes... 

How would you do this without the download attribute? Do keep in mind that when the browser makes the request to the bank site it includes the users cookies for bank.com. Generally these cookies are what identifies the user to the bank.

> Would it be possible to implement it with same-origin and CORS
> (Access-Control-Allow-Origin) in mind if you are questioning cross origin
> security? This is very useful feature for web applications (create Blob
> using JS and let user download it with some meaningful name)

Google was opposed to using CORS for this.
Comment 8 Bronislav Klučka 2011-10-10 11:11:43 PDT
(In reply to Jonas Sicking (:sicking) from comment #7)
> 
> How would you do this without the download attribute? Do keep in mind that
> when the browser makes the request to the bank site it includes the users
> cookies for bank.com. Generally these cookies are what identifies the user
> to the bank.
Oh i see what you meant, looking at that URL it does not seem to be behind login (cookies)... sorry. This is of course true, I cannot bypass that...

BTW. I can still write "to save this file please right click on the link and select 'save link as'" next to the link.... I wonder how many would blindly follow :)

> 
> > Would it be possible to implement it with same-origin and CORS
> > (Access-Control-Allow-Origin) in mind if you are questioning cross origin
> > security? This is very useful feature for web applications (create Blob
> > using JS and let user download it with some meaningful name)
> 
> Google was opposed to using CORS for this.

Well there can be notification or deny/allow mechanism when downloading from another origin (e.g. like in case of geolocation API). Or not to send cookies in case of cross origin request with download attribute. Or Mozilla can implement only same origin (and local [blob URL and FileSystemAPI URL]) at first (I really actually do not care that much about cross origin).

Is this attribute something Mozilla is seriously considering as useful and want to have or "yeh... well... rather not..."? I'm developing application using BlobBuilder and allowing users to download data with some intelligent name so I'm wondering whether I can proceed and wait until FF will catch up in few weeks/months or nobody really knows at this point?
Comment 9 Bronislav Klučka 2011-10-10 11:42:16 PDT
http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#downloading-resources
the 12th point in process starting with "Let filename be the void value." should address cross origin problem.
Comment 10 Jonas Sicking (:sicking) No longer reading bugmail consistently 2011-10-10 12:43:12 PDT
For same-origin this is definitely something that we want to implement. However if you're using BlobBuilder, and thus are using Blobs, I suspect what you want is FileSaver, no?

(In reply to Bronislav Klučka from comment #9)
> http://www.whatwg.org/specs/web-apps/current-work/multipage/links.
> html#downloading-resources
> the 12th point in process starting with "Let filename be the void value."
> should address cross origin problem.

I don't see why it would?
Comment 11 Bronislav Klučka 2011-10-10 20:42:39 PDT
(In reply to Jonas Sicking (:sicking) from comment #10)
> For same-origin this is definitely something that we want to implement.
> However if you're using BlobBuilder, and thus are using Blobs, I suspect
> what you want is FileSaver, no?

Yes, FileSaver would be great as well, but no browser seems to be implementing it (in some near future) and download attribute is very easy way to do the same = save file to local file system (actual file system, not FileSystem API file system)
I've done some test on weekend how to get file from webapp to disk
http://www.webnt.cz/demos/034_a_download/  (Chrome only at this point)
using download attribute or drag & drop on actual file or generated file (blob). The last example (span) shows how to download Blob without actually having A element (by creating it on the fly)...


> 
> (In reply to Bronislav Klučka from comment #9)
> > http://www.whatwg.org/specs/web-apps/current-work/multipage/links.
> > html#downloading-resources
> > the 12th point in process starting with "Let filename be the void value."
> > should address cross origin problem.
> 
> I don't see why it would?

"Act in a user-agent-defined manner to safeguard the user from a potentially hostile cross-origin download. If the download is not to be aborted, then let filename be set to the user's preferred file name or to a file name selected by the user agent, and jump to the step labeled "sanitize" below.

If the algorithm reaches this step, then a download was begun from a different origin than the resource being downloaded, and the origin did not mark the file as suitable for downloading, and the download was not initiated by the user. This could be because a download attribute was used to trigger the download, or because the resource in question is not of a type that the user agent supports.

This could be dangerous, because, for instance, a hostile server could be trying to get a user to unknowingly download private information and then re-upload it to the hostile server, by tricking the user into thinking the data is from the hostile server.

Thus, it is in the user's interests that the user be somehow notified that the resource in question comes from quite a different source, and to prevent confusion, any suggested filename from the potentially hostile interface origin should be ignored."

So you can abort such cross origin download, you can notify user about cross domain download, you can ignore download attribute....
Comment 12 Jonas Sicking (:sicking) No longer reading bugmail consistently 2011-10-10 20:54:21 PDT
Well, if we abort such downloads then we're back to not supporting cross-site uses of the download attribute :-)

Except in the rare case when the resource already sets Content-Disposition:attachment, in which case the download attribute added no value.

So yes, I'm all for supporting the download attribute for same-origin contents.
Comment 13 Bronislav Klučka 2011-10-10 20:57:55 PDT
As I have said before, supporting same-origin, Blob URL, FileSystem URL for start would be a great step forward and apparently according to spec :)
Comment 14 David Karger 2011-12-18 21:25:21 PST
(In reply to Jonas Sicking (:sicking) from comment #5)
> insert something like the following in the page:
> 
> <a href="http://bank.com/statement.cgi" download="statement.html">
> 
> The actual URL depends on the bank of course.
> 
> When the user clicks such a link, the user will be prompted if they want to
> download. It seems very easy for the user to make the mistake of thinking
> that something on the original website is being downloaded, and not
> something from bank.com.

I'm confused about this example.  Why does explicitly setting the download file name make this attack more effective than without it?  Even without the download attribute, a user may still download the file.  Which can then be uploaded to a different site as you said.  One could argue that it's a little harder if you don't know the filename of the download, but much of the time this filename will be fixed (e.g. "bank-statement.pdf") and thus knowable.
Comment 15 Jonas Sicking (:sicking) No longer reading bugmail consistently 2011-12-19 02:24:07 PST
The problem isn't in being able to select the name, but rather in being able to force a download at all.

Note that http has a specific mechanism for telling the browser that a response is so sensitive that it can't be cached on disk, only in memory. For example so that it doesn't linger around in case of a computer crash.

Many banks use this mechanism.

It would seem silly if we honored the bank telling us that a resource is so sensitive that we can't cache it to disk, and then turn around and gladly honor another websites request to not just store that resource in the cache, but permanently on the users desktop (or whatever the default save location is)
Comment 16 Bronislav Klučka 2011-12-19 03:29:38 PST
(In reply to Jonas Sicking (:sicking) from comment #15)

I'm confused here... isn't storing on users desktop exactly what browsers do at this point after clicking on a element with resource, that cannot be displayed by browser? Isn't it what browsers do when user right click on a element and select "save target as" even for resources that can be displayed by browser? This is for your "and then turn around and gladly honor another websites request", we do that already...

How about respecting always this HTTP mechanism (even if download attribute is specified) an in other cases respect the download attribute? Author will probably not use this HTTP mechanism and download attribute together (since it does not make any sense) and altering webpage (Firebug, WebKit Inspector) will not compromise secret information.
Comment 17 David Karger 2012-01-04 23:04:22 PST
(In reply to Jonas Sicking (:sicking) from comment #15)

So this is saying it would be a bad idea to allow the page to force a download.  But that's different from allowing the page to suggest a filename if the _user_ decides to download.

> The problem isn't in being able to select the name, but rather in being able
> to force a download at all.
> 
> Note that http has a specific mechanism for telling the browser that a
> response is so sensitive that it can't be cached on disk, only in memory.
> For example so that it doesn't linger around in case of a computer crash.
> 
> Many banks use this mechanism.
> 
> It would seem silly if we honored the bank telling us that a resource is so
> sensitive that we can't cache it to disk, and then turn around and gladly
> honor another websites request to not just store that resource in the cache,
> but permanently on the users desktop (or whatever the default save location
> is)
Comment 18 Jonas Sicking (:sicking) No longer reading bugmail consistently 2012-01-05 02:26:56 PST
Please note that the download attribute has two features:

1. When the user simply clicks a link like <a href="..." download="foo.html"> the
   browser will pop up a save-as dialog, rather than navigating to the clicked link.
2. When the file is saved, either by simply clicking the link, or when right-clicking
   and choosing "save link as" the name of the saved file is determined by the
   value of the download attribute.

The '2' part I completely agree is not a security problem. The '1' part is what makes me nervous.
Comment 19 Bronislav Klučka 2012-01-05 03:11:45 PST
(In reply to Jonas Sicking (:sicking) from comment #18)
> Please note that the download attribute has two features:
> 
> 1. When the user simply clicks a link like <a href="..."
> download="foo.html"> the
>    browser will pop up a save-as dialog, rather than navigating to the
> clicked link.
>
>  The '1' part is  what makes me nervous.

but browsers already do that... they navigate to content browsers can display (html, text, image, pdf) and download content they cannot display. No issue what so ever.

And that is problem from application point of view... one has to do right click -> "save link as" to force download of any content. That's fine for web pages, but just annoying for applications.

But again, we already allow people to download dangerous executables from web without any concern... allowing them to simply download image or text or HTML?
Comment 20 Jonas Sicking (:sicking) No longer reading bugmail consistently 2012-01-05 03:53:40 PST
We've always let *users* choose to download anything from any website.

Point 1 allows *webpages* to make the user download something from another site. That is totally different.

To make an example:

You can today go to your bank and download a bank statement.

You can also go to evil.com which could link to your bank statement and hope that you right-click and select "save link as". But evil.com can't do much other than hope that you right-click and choose that option.

Point 1 means that if you navigate to evil.com, evil.com can make you download your bank statement anytime you click anywhere on the page. With very little indication that that is what you are downloading.


I hope that makes the difference clear.
Comment 21 Bronislav Klučka 2012-01-05 07:34:08 PST
(In reply to Jonas Sicking (:sicking) from comment #20)
> I hope that makes the difference clear.

Yes, but I do not see any security risks here, evil.com will not get any secure data from that. You said it yourselves: there is always an option to right click. So if I want to be evil today, I can instruct user to right click and save data and the upload them back to my evil site. Tomorrow? I can let user download it with left click and upload those data to me... There's no new level of risk involved.

Frankly I'm beginning to be a little worried. This security paranoia is effectively colliding with creating real application development environment and sadly winning... I do understand the need for security, but at the end it's user responsibility. Nobody'd talking here about silently saving malicious data on user's computer and running them.
With such approach we would never have hypertext at all... because some sites can look like other (phishing), so wouldn't it be more secure to simply disallow user to click on link to another site, force every link to be within domain?

There can always be warning bar (as for GeoLocation) involved in case of cross-domain use of download attribute ("you are downloading data from remote site: disallow | allow this time | allow always access from evil.com to bank.com")
Comment 22 Bronislav Klučka 2012-01-05 07:36:11 PST
(In reply to Jonas Sicking (:sicking) from comment #20)
> We've always let *users* choose to download anything from any website.
> 
> Point 1 allows *webpages* to make the user download something from another
> site. That is totally different.
> 
> I hope that makes the difference clear.

By the way, again, browsers allow "*webpages* to make the user download something from another site." just not certain content at this point (a can download .exe, i cannot download .html without right click)
Comment 23 Jonas Sicking (:sicking) No longer reading bugmail consistently 2012-01-05 09:16:47 PST
Arg, we're going in circles. Please read the rest of the comments in the bug.
Comment 24 David Karger 2012-01-17 22:29:36 PST
So I've gotten a little lost reading all these comments.  I'm still trying to address a concrete problem with a web app I'm developing.  My app creates some content on the *client*, then, in order to deliver it to the user, embeds that content in a data url and calls window.open on the url.  The result is a dialog saying "you have chosen to open <large amount of gibberish>" with "open with" and "save as" options.  If I click "save as", the default filename is "8Z_onkyL" .  This really seems not particularly user friendly.  I'd like to improve that with a download= attribute that sets a more natural default filename.  I don't see this as creating a security threat, since a download from a _server_ sets the filename based on the tail of the download url, which can be anything a server wants it to be.
Comment 25 Bronislav Klučka 2012-01-18 04:48:23 PST
(In reply to David Karger from comment #24)
my point all the time :) but Jonas apparently has no issue regarding same-origin implementation, so this case you are describing will be addressed by FF developers, hopefully.

Brona
Comment 26 David Humphrey (:humph) 2012-03-05 11:51:27 PST
http://html5-demos.appspot.com/static/a.download.html
Comment 27 Paul Neave 2012-06-09 09:14:50 PDT
Please implement this!

As you can see from this demo: http://eligrey.com/demos/FileSaver.js/ saving a user-generated file in the browser is tremendously useful. The user can still decide whether they accept to download the file or not, once the download dialog/window appears.

Not implementing <a download=""> leaves us to throw users into an awfully confusing situation where the apparently downloaded file is simply opened in a new tab/window.

See also: http://developers.whatwg.org/links.html#downloading-resources
Comment 28 Nathan Froyd [:froydnj] 2012-06-09 11:04:01 PDT
*** Bug 747357 has been marked as a duplicate of this bug. ***
Comment 29 Julian Reschke 2012-07-22 01:00:10 PDT
(In reply to Paul Neave from comment #27)
> See also: http://developers.whatwg.org/links.html#downloading-resources

Note that this is only in the "WHATWG" version of HTML for now.
Comment 30 gooddanny 2012-07-22 04:12:49 PDT
I got a same use case and issue as David Karger's, same origin policy is fine. so maybe someone can implement this first as this one seems agreed by all.
Comment 31 Matthias Versen [:Matti] 2012-08-20 15:25:08 PDT
*** Bug 784119 has been marked as a duplicate of this bug. ***
Comment 32 Andy VanWagoner 2012-08-29 15:39:46 PDT
This is extremely useful for downloading content generated in javascript. Currently the workflow is to send the content to the server, which then just spits it back out. The content does a round trip to the server which is completely unnecessary. My use case is for creating links like so:

<a download="mine.whatever" href="data:application/whatever;base64;...">Download</a>
Comment 33 Robert Longson 2012-09-03 07:48:36 PDT
*** Bug 787941 has been marked as a duplicate of this bug. ***
Comment 34 Yoni Jah 2012-09-11 04:34:26 PDT
(In reply to Bronislav Klučka from comment #6)

I must say I find it hard to understand the security issues.
since this is just an info attribute allowing to indicate a link as being downloadable. untill now you could only do this by setting a specific headers in the response form the server which is not an option if you want to set it from the client side (like in data URIs).

now I'm sure that we can all agree that in data URIs there is no security issue.
since this content will always come form the page origin and the download tag will only indicate the name of the downloaded file.
the only thing an "attacker" can do here, is force you to get a download dialog for file type that are usually run in the browser as image/text/html.
and since automatically running a file is way more dangerous then prompting for downloading it, I think we can rule this option out as being a security issue
* with that in mind the download tag should of course only allow setting of a file name and not the path for it to be saved so values like "/etc/hosts" "../.bashrc" should not be allowed, but this should be obvious and also if you get the file name from the headers.

The more serious security issue might be from using as you mentioned a cross origin request to a different domain, the user might think he is downloading a file form a illegitimate site but will actually be directed to an evil site download.

the first assumption is wrong. since the site triggering the request (using the download tag ) is the malicious site ( or a hacked site). so we might say that if the user consider this site as safe he is wrong, any malicious content can be added to the site and you do not need any cross origin request to get it.
more over lets say you still want to cause the user to download a malicious file form a 3rd party evil site. all this site has to do is set the response header to indicate the file is downloadable (as with any other download) and the user will get a download notification exactly as would happen with a download tag.

the more serious issue with CORS downloads is if a malicious site forces a download of a file form a legitimate  site and some how gets access to its content. so lets say I download the user gmail inbox page and explore its messages.
in this case an evil site will have to fool the user into downloading the file and uploading it back to the server, so lets say we have a gmail.com/inbox.html actually contains all the user mail messages and the attacker sites offers a download link for a coupon file, that should be uploaded to another evil site. the coupon will supposedly offer a 30% discount on a new Ipad. the download link will actually point to gmail.com/inbox.html and will download it as "30off.coupon", the if the user will download this file and upload it without checking it's content the evil site will get the user "coupon" and so its inbox content.
I think this security issue is much more serious then just the use of a download tag (user downloading and uploading files to an unknown site)
but it can be avoided by ignoring the download tag for setting the file name specifically for external files and only use it for data URIs (which are not affected form this issue).
developers will be able to set file names to data URIs, and if a specific link has to get a different name then what its URL indicates it can still be set in the server response headers.

Now I'm not coming to tell any one security is not an issue (you should always try to consider all the implications of implementing a new feature), I'm more trying to push the discussion and activity on this issue since I think this is a really needed feature and I'm trying to make the discussion about it more active.
Comment 35 Artem Skoretskiy 2012-09-20 02:12:36 PDT
(In reply to Yoni Jah from comment #34)

I'm totally agree with you.

There is *VERY* small security difference between: a) A without "download" attribute and b) with it. 

Let's compare it:

a) 1. User sees the link and read the text. The text can be everything (e.g. "my secure report").
   2. User hover the link and see the URL. It can be everything (e.g. http://mysite.com/report.xls) and can lead to *ANY* external site in the internet.
   3a. User click on the link. Depending on the server response -- it would either open it (e.g. HTML or text) or open dialog for saving the file (see step 4).
   3b. User do right-click on link and select to save the file.
   4. "Save file" dialog appear if user did not select "Do it automatically". The file name that is shown here depends on the server response (it could send header "Content-Disposition: attachment; filename='<name>'") and can be completely *DIFFERENT* from the file name mentioned in URL (e.g. virus.exe).
   5. User select what to do with file -- save or open it (in given program).

b) 1. the same
   2. the same
   3a. It would always lead to saving file in spite of server response.
   3b. the same
   4. the same but filename is got from "download" attribute, not server response.
   5. the same.

Let's summarize difference:
 1. User will be prompted to download file even if file is supported by browser -- e.g. HTML or image (if it was a ZIP, EXE or binary -- user would have been prompted to download anyway).
 2. Filename for saving will be generated by the page, not the server that holds the resource.

What would be the impact?
 1. User may download HTML / text / image instead of just opening it.
 2. User may have file name different than one provided by external resource.

That's it! Issue 1 is not a security at all, issue 2 as well -- user will be warned about the file type before downloading and opening it.

Also any file name generation can be easily done on server (and it is being used already) and we see no complains yet.

One more thing -- Google Chrome already implemented it since Chrome 14. They are really concerned about security (recall their sandbox model and long adoption of security-impacted features -- e.g. WebGL or files storage) but have it. They must had really good reasons to have it in mainline -- even not experimental branch.
Comment 36 Paul Neave 2012-09-20 06:25:48 PDT
As far as I can tell, the only real reason Mozilla refuse to implement the download attribute is because it is not a W3C standard. It is only in the WHATWG version of HTML: http://developers.whatwg.org/links.html#downloading-resources

The security risks are nonexistent and it would obviously make a good addition. So I'd suggest that those who are interested join the W3C lists at https://www.w3.org/Bugs/Public/ and propose that <a download> be added to the official W3C spec. Then perhaps Mozilla would be more willing to add support.
Comment 37 Mounir Lamouri (:mounir) 2012-09-20 06:49:48 PDT
(In reply to Paul Neave from comment #36)
> As far as I can tell, the only real reason Mozilla refuse to implement the
> download attribute is because it is not a W3C standard. It is only in the
> WHATWG version of HTML:
> http://developers.whatwg.org/links.html#downloading-resources
> 
> The security risks are nonexistent and it would obviously make a good
> addition. So I'd suggest that those who are interested join the W3C lists at
> https://www.w3.org/Bugs/Public/ and propose that <a download> be added to
> the official W3C spec. Then perhaps Mozilla would be more willing to add
> support.

This is not true. Mozilla isn't against implementing something that is only specified in WHATWG version of HTML.
Comment 38 Artem Skoretskiy 2012-09-20 07:03:38 PDT
(In reply to Mounir Lamouri (:mounir) from comment #37)

> This is not true. Mozilla isn't against implementing something that is only
> specified in WHATWG version of HTML.

Then let's change status from "NEW" to "CONFIRMED" an make someone work on it :)
Comment 39 Yoni Jah 2012-09-20 08:03:21 PDT
(In reply to Paul Neave from comment #36)
> As far as I can tell, the only real reason Mozilla refuse to implement the
> download attribute is because it is not a W3C standard. It is only in the
> WHATWG version of HTML:
> http://developers.whatwg.org/links.html#downloading-resources
> 
> The security risks are nonexistent and it would obviously make a good
> addition. So I'd suggest that those who are interested join the W3C lists at
> https://www.w3.org/Bugs/Public/ and propose that <a download> be added to
> the official W3C spec. Then perhaps Mozilla would be more willing to add
> support.

this is weird because in MDN this attribute is mention it as part of html5 -
https://developer.mozilla.org/en-US/docs/HTML/Element/a#attr-download
and it is very confusing since it doesn't mention that firefox doesn't actually support this feature
Comment 40 Kyle Huey [:khuey] (Exited; not receiving bugmail, email if necessary) 2012-09-20 08:09:41 PDT
The main reason this isn't happening right now is because nobody is working on it.  I think we agree that the security concerns are manageable.  We're certainly ok with implementing same-origin download attribute, and probably a cross-origin download attribute with CORS.

And we're absolutely not opposed to implementing things that are only in the WHATWG version of HTML.
Comment 41 Boris Zbarsky [:bz] (still a bit busy) 2012-09-20 10:31:55 PDT
> Then let's change status from "NEW" to "CONFIRMED" an make someone work on it :)

NEW does mean CONFIRMED.

And thank you for volunteering!
Comment 42 Marco Castelluccio [:marco] 2012-09-20 15:16:27 PDT
(In reply to Boris Zbarsky (:bz) from comment #41)
> And thank you for volunteering!

Just wondering, is this a joke? Or is he starting to work on this for real?
Comment 43 Boris Zbarsky [:bz] (still a bit busy) 2012-09-20 17:50:24 PDT
_I_ certainly wasn't joking.  Just acting on comment 38's suggestion.
Comment 44 Marco Castelluccio [:marco] 2012-09-21 02:26:14 PDT
Let's set the real status of this bug.
Artem, if this bug is a priority for you, you can either vote it (near the "Importance" field) or work on it or pay someone else to work on it.
Comment 45 David Bruant 2012-09-22 03:05:17 PDT
(In reply to Yoni Jah from comment #39)
> this is weird because in MDN this attribute is mention it as part of html5 -
> https://developer.mozilla.org/en-US/docs/HTML/Element/a#attr-download
> and it is very confusing since it doesn't mention that firefox doesn't
> actually support this feature
True. I've added the NeedsCompatTable tag on the page. It would be nice to have a compatibility table that takes attributes into account, very much like what can be seen in the <input> page https://developer.mozilla.org/en-US/docs/HTML/Element/Input

I take this opportunity to inform you that Mozilla organizes a doc sprint in London next week-end https://wiki.mozilla.org/MDN/Doc_Sprints
It can be attended in-person if you're in London (in the London MozSpace) or virtually (everyone just connects to the same IRC channel).
Contact me or Janet Switcher (jswisher@mozilla.com) if you're interested in participating, even if just for one hour.
Comment 46 Tom Schuster [:evilpie] 2012-09-22 05:39:45 PDT
I would be interested in working on this, but I am not really sure how to fix this.
I already added a download attribute to nsIDOMHTMLAnchorElement. Than I looked nsDocShell::OnLinkClickSync and I figured I somehow need to change something so we end up calling nsIExternalHelperAppService. The hard part I think is changing the path through all of this code.
Comment 47 Josh Matthews [:jdm] (on vacation until Dec 5) 2012-09-22 09:48:28 PDT
My inclination would be to add a filenameHint attribute to nsIChannel that GetFilenameAndExtensionFromChannel would attempt to use first. Dunno how keen the necko people would be on that, so let's get Jason's thoughts.
Comment 48 Kyle Huey [:khuey] (Exited; not receiving bugmail, email if necessary) 2012-09-22 17:19:15 PDT
You may find the patch in Bug 665216 to be of use.
Comment 49 Tom Schuster [:evilpie] 2012-09-23 05:04:22 PDT
(In reply to Kyle Huey [:khuey] (khuey@mozilla.com) from comment #48)
> You may find the patch in Bug 665216 to be of use.
Great Kyle, this patch showed me an easy way to fix this! Combining your patch and my patch, we should be able to force a download and even specify a file-name.

I just tested this with a Blob and it seem to work. One thing that needs to be looked at, how we could allow drag and drop downloading like Chrome.
Comment 50 Tom Schuster [:evilpie] 2012-09-23 05:06:48 PDT
Created attachment 663804 [details] [diff] [review]
wip patch

With this patch, clicking on the download link, should show a download box. I still need to look into the same-origin restriction.

<script>
var blob = new Blob(['test']);

var a = document.createElement('a');
a.download = true;
a.href = window.URL.createObjectURL(blob)
a.textContent = 'Download';

window.document.body.appendChild(a);
</script>
Comment 51 Mounir Lamouri (:mounir) 2012-09-23 05:24:18 PDT
For the same origin check, you can probably use GetASCIIOrigin or GetUTFOrigin from nsContentUtils. I guess the check has to happen between the current document and the targeted download?
Comment 52 Jason Duell [:jduell] (needinfo me) 2012-09-28 12:41:06 PDT
> My inclination would be to add a filenameHint attribute to nsIChannel that 
> GetFilenameAndExtensionFromChannel would attempt to use first

Talked with biesi on IRC--we came to conclusion that the right thing here would be to make nsIChannel.contentDispositionFilename no longer readonly, so code could write to that.  Filed bug 795442
Comment 53 Tom Schuster [:evilpie] 2012-09-29 06:09:18 PDT
Created attachment 666200 [details] [diff] [review]
WIP v2

This now depends on my patch in Bug 795442. I also implemented some same-origin check, no idea if this is the right way.
Comment 54 Boris Zbarsky [:bz] (still a bit busy) 2012-09-29 07:43:42 PDT
The security check is certainly wrong afaict.  I thought I'd told someone how to do it right, already....

In any case, the right place to do it is probably a CheckMayLoad check at the place where we do the existing CheckLoadURI for link loads.
Comment 55 Tom Schuster [:evilpie] 2012-10-05 12:59:29 PDT
Created attachment 668574 [details] [diff] [review]
WIP v3

Now with the ability to name the downloaded file. I removed the security check and some stuff still behaves _right_, weird.
Comment 56 Tom Schuster [:evilpie] 2012-11-03 10:50:22 PDT
Test page, going to add a few examples:
http://jsfiddle.net/G5hyy/
Comment 57 Tom Schuster [:evilpie] 2012-11-03 11:07:21 PDT
(In reply to Boris Zbarsky (:bz) from comment #54)
> The security check is certainly wrong afaict.  I thought I'd told someone
> how to do it right, already....
> 
> In any case, the right place to do it is probably a CheckMayLoad check at
> the place where we do the existing CheckLoadURI for link loads.

I don't see either of these being used in OnLinkClickSync, InternalLoad or DoURILoad. I think we might want to allow navigating to the linked element even when it is on a different domain, so in practice ignore the download attribute. Would this allow for this flexibility? Chromium allows downloading cross-domain stuff btw.
Comment 58 Boris Zbarsky [:bz] (still a bit busy) 2012-11-03 11:53:10 PDT
> I don't see either of these being used in OnLinkClickSync, InternalLoad or DoURILoad.

Yes, they happen way before that.  See nsContentUtils::TriggerLink.

> so in practice ignore the download attribute. Would this allow for this flexibility?

Yes.  You'd just need to make the download attribute bits an argument to OnLinkClick, and get it off the node in TriggerLink.
Comment 59 Tom Schuster [:evilpie] 2012-11-03 14:39:31 PDT
Created attachment 678054 [details] [diff] [review]
WIP v4

Thanks to bz's help, this is now working correctly. He also already told me about the fun that is ahead of me to write tests for this. I am going to look at Drag 'n Download in another bug.
Comment 60 Tom Schuster [:evilpie] 2012-11-07 09:26:16 PST
I need some help with the tests. I tried to search for 'Content-Disposition' assuming that test for that would be useful and they don't look like that. Searching for 'download' comes up with test for the download manager.

I actually just want to test this in a very simple way.

If we click on a link with the download attribute, make sure the download box opens up with the right filename in it. In some cases we don't want to allow the download (cross-origin), so we should test whether we navigated to that page.
Comment 61 Boris Zbarsky [:bz] (still a bit busy) 2012-11-07 23:11:38 PST
> make sure the download box opens up with the right filename in it.

You mean the filepicker?  That would be kinda bad, since it's a modal OS dialog, so if it comes up you're sort of stuck.

I think you basically want to see whether you can repurpose the download manager tests here.  :(
Comment 62 Bronislav Klučka 2012-11-07 23:47:55 PST
This should follow browser settings, either download directly to download folder with suggested name or open filepicker (Save As dialog)
Comment 63 Boris Zbarsky [:bz] (still a bit busy) 2012-11-08 00:03:17 PST
We're talking about the _test_ here, not what happens when a user uses the browser.  In the latter case, it'll follow browser settings, obviously.
Comment 64 Mounir Lamouri (:mounir) 2012-11-08 03:39:36 PST
Tom, can't you use nsIFilePicker mock? We have that in SpecialPowers if I remember correctly, The default file name should be available from nsIFilePicker.defaultString, right?
Comment 65 Tom Schuster [:evilpie] 2012-11-08 06:58:58 PST
I am talking about this: http://imgur.com/UTM94.
Comment 66 Mounir Lamouri (:mounir) 2012-11-08 07:48:32 PST
Can we implement a mock for that?
Comment 67 Josh Matthews [:jdm] (on vacation until Dec 5) 2012-11-08 10:18:59 PST
There is already a MockFilePicker object: http://mxr.mozilla.org/mozilla-central/search?string=mockfilepicker
Comment 68 Mounir Lamouri (:mounir) 2012-11-08 10:22:00 PST
(In reply to Josh Matthews [:jdm] from comment #67)
> There is already a MockFilePicker object:
> http://mxr.mozilla.org/mozilla-central/search?string=mockfilepicker

Josh, that's what comment 64 was saying but that mock doesn't implement the "Do you want to save or open this file" dialog. We need another mock for that I would say.
Comment 69 Tom Schuster [:evilpie] 2012-11-12 11:37:51 PST
I think http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/downloads/tests/chrome/test_unknownContentType_dialog_layout.xul could be edited to test something like this. But it feels kinda wrong.
Comment 70 Tom Schuster [:evilpie] 2012-11-17 07:43:21 PST
Created attachment 682758 [details] [diff] [review]
Test WIP

The way I implemented the wait for window, test, continue is ultra ugly. I hope we have some better way to do this. This is lacking tests for cross-origin links that should just navigate away.
Comment 71 Tom Schuster [:evilpie] 2012-11-20 07:00:24 PST
Created attachment 683577 [details] [diff] [review]
v1

This is more or less the same as WIP v4. bz suggested truncating the aTargetSpec, because <a download target="_blank"> should start a download instead of navigating away.
Comment 72 Tom Schuster [:evilpie] 2012-11-20 07:04:33 PST
Created attachment 683580 [details] [diff] [review]
tests v1

This tests:
- data uris
- video url with empty download
- video url with explicit file name
- data uri with target
- cross origin url

I just tests that the "Opening test.file" "Open With" dialog is opened with the correct filename.
Comment 73 Olli Pettay [:smaug] 2012-11-20 11:21:15 PST
Comment on attachment 683577 [details] [diff] [review]
v1

># HG changeset patch
># Parent cd8533b0fae7641fca51d4adf5f61bbfb1d719ec
># User Tom Schuster <evilpies@gmail.com>
>
>diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
>--- a/content/base/src/nsContentUtils.cpp
>+++ b/content/base/src/nsContentUtils.cpp
>@@ -4668,37 +4668,56 @@ nsContentUtils::TriggerLink(nsIContent *
> 
>   nsILinkHandler *handler = aPresContext->GetLinkHandler();
>   if (!handler) {
>     return;
>   }
> 
>   if (!aClick) {
>     handler->OnOverLink(aContent, aLinkURI, aTargetSpec.get());
>-
>     return;
>   }
> 
>   // Check that this page is allowed to load this URI.
>   nsresult proceed = NS_OK;
> 
>   if (sSecurityManager) {
>     uint32_t flag =
>       aIsUserTriggered ?
>       (uint32_t)nsIScriptSecurityManager::STANDARD :
>       (uint32_t)nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT;
>     proceed =
>       sSecurityManager->CheckLoadURIWithPrincipal(aContent->NodePrincipal(),
>                                                   aLinkURI, flag);
>   }
> 
>+  // A link/area element with a download attribute is allowed to set
>+  // a pseudo Content-Disposition header.
>+  bool forceDownload = false;
>+  nsString fileName;
>+  if ((aContent->Tag() == nsGkAtoms::a || aContent->Tag() == nsGkAtoms::area) &&

aContent->IsHTML(nsGkAtoms::a) || aContent->IsHTML(nsGkAtoms::area)



>+      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::download, fileName)) {
>+    forceDownload = true;
>+  }
>+  // For security reasons we only allow websites to declare same-origin resources
>+  // as downloadable. If this check fails we will just do the normal thing
>+  // (i.e. navigate to the resource).
>+  if (forceDownload) {
>+    if (NS_FAILED(aContent->NodePrincipal()->CheckMayLoad(aLinkURI, false, true))) {
>+      forceDownload = false;
>+    }
>+  }

This all could be
bool forceDownload = NS_SUCCEEDED(proceed) &&
                     (aContent->IsHTML(nsGkAtoms::a) || aContent->IsHTML(nsGkAtoms::area)) &&
                     aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::download, fileName) &&
                     NS_SUCCEEDED(aContent->NodePrincipal()->CheckMayLoad(aLinkURI, false, true));



>     NS_IMETHOD OnLinkClick(nsIContent* aContent,
>         nsIURI* aURI,
>         const PRUnichar* aTargetSpec,
>+        bool aForceDownload,
>+        const nsString& aFileName,
Since the method takes PRUnichar* params anyway, perhaps use that for aFileName too.
That way null aFileName could mean no forced download.
Forced to pass EmptyString around feels a bit ugly in this case.



Would like to see a new patch.
Comment 74 Olli Pettay [:smaug] 2012-11-20 11:32:57 PST
Comment on attachment 683580 [details] [diff] [review]
tests v1

Would be nice if someone more familiar with firefox UI code could look at this too - to ensure that we test all the cases we should be testing.
Comment 75 Boris Zbarsky [:bz] (still a bit busy) 2012-11-20 11:39:27 PST
> aContent->IsHTML(nsGkAtoms::a) || aContent->IsHTML(nsGkAtoms::area)

I think we should allow svg:a too.  And non-html:area would never call this method anyway..

> Since the method takes PRUnichar* params anyway, perhaps use that for aFileName too.
> That way null aFileName could mean no forced download.

Or we could use a void string to indicate that?
Comment 76 Olli Pettay [:smaug] 2012-11-20 11:42:23 PST
(In reply to Boris Zbarsky (:bz) from comment #75)
> 
> Or we could use a void string to indicate that?
That would be ok too if the other parameter was changed to be const nsAString&.
I want some consistency in the parameter types :)
Comment 77 Olli Pettay [:smaug] 2012-11-20 11:47:35 PST
(In reply to Boris Zbarsky (:bz) from comment #75)
> I think we should allow svg:a too.
Well, there is no spec for that, I believe, but yeah, makes sense.
Comment 78 Tom Schuster [:evilpie] 2012-11-26 10:21:56 PST
Created attachment 685231 [details] [diff] [review]
v2

Addressed review comments, but still need to change the oder parameters to nsAString.
Comment 79 Tom Schuster [:evilpie] 2012-11-26 10:41:20 PST
Created attachment 685244 [details] [diff] [review]
v2.1

I am now using NullString(), which makes this a lot nicer.
Comment 80 Tom Schuster [:evilpie] 2012-11-26 11:09:10 PST
Created attachment 685259 [details] [diff] [review]
change params to nsAString
Comment 81 Olli Pettay [:smaug] 2012-11-27 13:11:22 PST
Comment on attachment 685244 [details] [diff] [review]
v2.1

>+    if ((aContent->Tag() != nsGkAtoms::a && aContent->Tag() != nsGkAtoms::area) ||

I'd prefer using aContent->IsHTML(...), and  aContent->IsSVG(...)
That way it is clear which cases we're handling here.

> nsDocShell::InternalLoad(nsIURI * aURI,
>                          nsIURI * aReferrer,
>                          nsISupports * aOwner,
>                          uint32_t aFlags,
>                          const PRUnichar *aWindowTarget,
>                          const char* aTypeHint,
>+                         const nsAString &aFileName,
const nsAString& aFileName



>+   * @param aFileName       - Mon-void when link should be downloaded as.
>+                              the given filename.
Non-null
And there is extra . after as
Should there be 'the' before 'link'?


>    * @param aPostDataStream the POST data to send
>+   * @param aFileName non-void when link should be downloaded as the given file
non-null


>+   * @param aFileName non-void when link should be downloaded as the given file
non-null



Could you please test various protocols. You seem to test http: and data:.
Could you make sure also https: work. And ftp should work too, but I'm not sure how to
write mochitest for ftp: case.
I wonder how javascript: should be handled. Does the spec say anything about it?
Comment 82 Olli Pettay [:smaug] 2012-11-27 13:18:54 PST
I guess javascript: with download shouldn't do anything, and your patch probably even handles that, 
but please add a test.
Comment 83 Olli Pettay [:smaug] 2012-11-27 13:23:57 PST
Or no. javascript: channel doesn't seem to throw when setting contentdisposition.

Downloading the script data would be ok too. I don't see anything related to this in the spec.
Please test what other browsers do. A followup patch might be needed to sort this out.
Comment 84 Tom Schuster [:evilpie] 2012-11-28 04:45:51 PST
I will look at adding test for the other protocols. In Chrome a link with download and javascript: just does nothing.
Comment 85 Boris Zbarsky [:bz] (still a bit busy) 2012-11-28 07:39:40 PST
WebKit doesn't implement the whole "javascript: can return value" thing except in the special case of iframes; they actually handle it as a complete special-case, not via normal loading codepaths.  So testing Chrome for javascript: is pretty pointless... :(
Comment 86 Olli Pettay [:smaug] 2012-11-28 08:41:49 PST
Well, we need to figure out what javascript: + download should do in Gecko.
And whatever we decide, have a test for that.
Comment 87 flying sheep 2012-11-28 12:44:06 PST
hmm, i currently develop a webapp that, on click of a link, does the following:

1. prepare Blob https://developer.mozilla.org/en-US/docs/DOM/Blob
2. create object url https://developer.mozilla.org/en-US/docs/DOM/window.URL.createObjectURL
3. create link tag with download attribute
4. fake a click on that created link

it would be quite useful to let a link with href="javascipt:…" just download the URL that is returned by the supplied javascript expression.

then my code wouldn’t look like above, but let the link tag’s href just call a function consisting of steps 1&2 and returning the object url.
Comment 88 Jonas Sicking (:sicking) No longer reading bugmail consistently 2012-11-28 13:36:52 PST
I think we should do whatever is simplest implementat-wise. If simply ignoring the download attribute in that case is the simplest thing to do, I think that's fine. If running the javascript and offering to download any content that is returned, then I think that's totally fine too.
Comment 89 Jonas Sicking (:sicking) No longer reading bugmail consistently 2012-11-29 14:06:17 PST
(In reply to flying sheep from comment #87)
> hmm, i currently develop a webapp that, on click of a link, does the
> following:
> 
> 1. prepare Blob https://developer.mozilla.org/en-US/docs/DOM/Blob
> 2. create object url
> https://developer.mozilla.org/en-US/docs/DOM/window.URL.createObjectURL
> 3. create link tag with download attribute
> 4. fake a click on that created link
> 
> it would be quite useful to let a link with href="javascipt:…" just download
> the URL that is returned by the supplied javascript expression.

That is not how javascript URLs work. We wouldn't download the URL returned by the expressed, but we'd download what the expression returned.

If you have a Blob object that you want the user to download, either set the href attribute to the blob: url, or use the FileSaver API (once that's implemented)
Comment 90 flying sheep 2012-11-30 07:14:40 PST
(In reply to Jonas Sicking (:sicking) from comment #89)
> If you have a Blob object that you want the user to download, either
> set the href attribute to the blob: url, or use the FileSaver API
> (once that's implemented)

was just an idea. but since a onclick eventlistener is executed before the user clicks, one also can just set the href there: http://jsfiddle.net/8NKmJ/

(i left out the additional onfocus for non-mouse users in the onmouseover case: i guess it’s needed if the link is never actually hovered?)
Comment 91 Tom Schuster [:evilpie] 2012-12-02 02:40:23 PST
(In reply to Olli Pettay [:smaug] from comment #81)
> Comment on attachment 685244 [details] [diff] [review]
> v2.1
> 
> >+    if ((aContent->Tag() != nsGkAtoms::a && aContent->Tag() != nsGkAtoms::area) ||
> 
> I'd prefer using aContent->IsHTML(...), and  aContent->IsSVG(...)
> That way it is clear which cases we're handling here.
>
> > nsDocShell::InternalLoad(nsIURI * aURI,
> >                          nsIURI * aReferrer,
> >                          nsISupports * aOwner,
> >                          uint32_t aFlags,
> >                          const PRUnichar *aWindowTarget,
> >                          const char* aTypeHint,
> >+                         const nsAString &aFileName,
> const nsAString& aFileName
> 
> 
> 
> >+   * @param aFileName       - Mon-void when link should be downloaded as.
> >+                              the given filename.
> Non-null
> And there is extra . after as
> Should there be 'the' before 'link'?
> 
> 
> >    * @param aPostDataStream the POST data to send
> >+   * @param aFileName non-void when link should be downloaded as the given file
> non-null
> 
> 
> >+   * @param aFileName non-void when link should be downloaded as the given file
> non-null
> 
> 
I fixed these, but it would be great if you could use the review feature.
> 
> Could you please test various protocols. You seem to test http: and data:.
> Could you make sure also https: work. And ftp should work too, but I'm not
> sure how to
> write mochitest for ftp: case.
> I wonder how javascript: should be handled. Does the spec say anything about
> it?
I added a test for javascript:. I manually tested https:. But I am still missing tests for https: and ftp:. I am not sure how to these those.
Comment 92 Tom Schuster [:evilpie] 2012-12-02 12:57:59 PST
I just committed the current stuff. I am going to look into the other tests next week.

https://hg.mozilla.org/integration/mozilla-inbound/rev/a12cd43e6e02
https://hg.mozilla.org/integration/mozilla-inbound/rev/b2a92abab0d1
Comment 93 sys.sgx 2012-12-03 07:14:06 PST
Thanks Tom for the implementation :)

For consistency, can we merge this topic too: https://bugzilla.mozilla.org/show_bug.cgi?id=367231

Possibly, offering this solution as the final one?
I'm interested to know what people think of it.
Comment 95 Jonas Sicking (:sicking) No longer reading bugmail consistently 2012-12-04 00:12:35 PST
Tom: You rock!! This is awesome! Thank you so much for your help. Let us know if you are interested in helping on other things once this is fully fixed!
Comment 96 Tom Schuster [:evilpie] 2012-12-04 11:46:12 PST
So I think for ftp:// I need to load a page from ftp:// otherwise the download should be disallowed anyways.
Comment 97 Jonas Sicking (:sicking) No longer reading bugmail consistently 2012-12-04 14:11:49 PST
Yes, a different protocol or a different port means that it's a different origin.
Comment 98 sys.sgx 2012-12-04 15:37:55 PST
Are there any security issues related with this feature? Like creating a script that will auto download an executable file on the system? Should there be any filename filters?

Thanks
Comment 99 Stefan Kienzle 2012-12-05 05:27:36 PST
Firefox nightly 20.0a1 (2012-12-04) fires onbeforeunload event. I have no target set (target="_self" or anything else => same behavior).
Is this correct? Can i prevent this event?

Thanks
Comment 100 Tom Schuster [:evilpie] 2012-12-05 06:14:23 PST
This is a legitimate problem. Basically we just need to replicate what we do in the javascript: case and suppress it.
Comment 101 John Drinkwater (:beta) 2012-12-05 07:16:06 PST
Excellent, this even behaves well with middle‐click (opens content in new tab instead of download)! Have a bug open for Chromium http://code.google.com/p/chromium/issues/detail?id=116376 with their download behaviour overriding user intent.
Comment 102 Tom Schuster [:evilpie] 2012-12-05 10:05:28 PST
The problem in Comment 99 is actually pre-existing. This also happens for files served with Content-Disposition: attachment. I filled follow-up bug 818559 for this.
Comment 103 Boris Zbarsky [:bz] (still a bit busy) 2012-12-06 08:18:35 PST
We don't have a test infrastructure for FTP at all, so there's no point worrying about adding an ftp:// test.
Comment 104 Tom Schuster [:evilpie] 2012-12-06 10:31:04 PST
Created attachment 689272 [details] [diff] [review]
modified test for https
Comment 105 Yoni Jah 2012-12-06 22:32:08 PST
I just had one thought about security.
the file name form the download attribute should not change the original way firefox handles file names, so if the file already exists in the download folder the file should be saved with a number suffix (as happens with current downloads).

another thing that should be checked is that the filename only contains file names and no directories and if it does they should be ignored so we are sure the site is not able to set to local directory where the file will be saved.

I'm sorry if I'm just stating the obvious but I tried to see if this issue was discussed.
(I also tried to look in the code but I don't understand it we'll enough to understand how it'll behave)

p.s the work your guys are doing here is awesome and I'm sorry I couldn't be more helpful
Comment 106 Boris Zbarsky [:bz] (still a bit busy) 2012-12-06 22:40:38 PST
Yoni, the filename from this attribute is treated exactly like a filename from an HTTP Content-Disposition header.  In fact, the implementation basically synthesizes such a header, and then lets the rest of the system work as it normally would.  So all those things should be handled fine with this patch, I think.
Comment 107 Tom Schuster [:evilpie] 2012-12-07 08:08:49 PST
Thank you Olli. This bug is now done, I filed a Bug 819373 for handling Drag and drop.
https://hg.mozilla.org/integration/mozilla-inbound/rev/d6d585622ca7
Comment 109 turk.brandon 2012-12-11 08:11:19 PST
' Download "just some video" ' Just opens a link to the video rather than downloading it.
Similarly with images, the images open without downloading them with the appropriate name.

Additionally, shouldn't this download function affect "Save As..."?
Comment 110 Antoine 2012-12-14 04:30:10 PST
Is this really working as expected?
In Chrome, the download attribute behaves like the "Save As..." function on any type of content, not just data and javascript urls.
Comment 111 Tom Schuster [:evilpie] 2012-12-14 07:49:02 PST
>' Download "just some video" ' Just opens a link to the video rather than downloading it.
>Similarly with images, the images open without downloading them with the appropriate name.
Do you mean the test committed by this patch? Where are you getting this from?

>Additionally, shouldn't this download function affect "Save As..."?
In which way?

>In Chrome, the download attribute behaves like the "Save As..." function on any type of >content, not just data and javascript urls.
Could you please show us an example where the download is not working as expected? Please not we have stronger restrictions for the origin of the data you are allowed to download than Chrome, because we only allow same-origin downloads.

You can download from all kinds of URI types as along as they are same-origin.
Here an example for an image download. http://jsfiddle.net/vhbmQ/1/
Comment 112 Antoine 2012-12-14 08:02:55 PST
>we have stronger restrictions for the origin of the data you are allowed to download than Chrome, because we only allow same-origin downloads.
Okay, I see. This is a pretty heavy restriction, especially since downloadable content is usually served from a CDN or an alternate domain.
Comment 113 Boris Zbarsky [:bz] (still a bit busy) 2012-12-14 08:31:53 PST
Antoine, it's a necessary restriction to prevent this functionality being used to attack users.  Please read the whole bug: this was discussed at some length....
Comment 114 bno112300 2012-12-14 09:28:15 PST
(In reply to Boris Zbarsky (:bz) from comment #113)
> Antoine, it's a necessary restriction to prevent this functionality being
> used to attack users.

I get the feeling that everyone is overthinking this a little.
Wouldn't limiting the download location to certain areas, ensuring the name attribute does not contain any executable extensions or directory modifiers (such as / or \) and forcing the attribute to ignore certain unicode characters (such as RTL override) would stop the majority of exploits?

Alternatively, have the function turned off be default, or warn the user when it's being used.
Comment 115 turk.brandon 2012-12-14 16:48:40 PST
(In reply to Tom Schuster [:evilpie] from comment #111)
> >' Download "just some video" ' Just opens a link to the video rather than downloading it.
> >Similarly with images, the images open without downloading them with the appropriate name.
> Do you mean the test committed by this patch? Where are you getting this
> from?

The test in here: https://hg.mozilla.org/mozilla-central/rev/d6d585622ca7

> http://jsfiddle.net/vhbmQ/1/

Image download worked on that, but it doesn't seem to work when using a userscript (Ihavenoface's 4chan-x) with GreaseMonkey.
HTML produced:
<a download="8269171301_b6fed812cc_b.jpg" href="http://images.4chan.org/a/src/1355530839672.jpg" class="download_link entry focused">Download file</a>
All it does is open the image file in tab instead of in a download window. (Link will most likely be dead by the time you see this.)

> >Additionally, shouldn't this download function affect "Save As..."?
> In which way?

By changing the default name into the one recommended by the download attribute.
Currently if you do "Save Link/Image As..." it keeps the file's original name rather than using the recommended title given by the download attribute. I use Save As a lot as I like to categorize where I download specific things.
Comment 116 Stefan Kienzle 2013-02-14 01:26:30 PST
If html5 fullscreen mode is activated the save dialog exit the fullscreen mode.
Comment 117 Amiad 2013-03-14 07:51:08 PDT
I checked on Firefox 21 (Aurora) and this not work.
If I click on Video.ogg in test page the movie opened in the browser and not dowloaded.
https://hg.mozilla.org/mozilla-central/raw-file/d6d585622ca7/browser/base/content/test/download_page.html
Comment 118 Boris Zbarsky [:bz] (still a bit busy) 2013-03-14 08:14:44 PDT
That server is sending an explicit Content-Disposition header for that URL, which overrides the hint from the "download" attribute.
Comment 119 Amiad 2013-03-14 08:55:40 PDT
I checked this on Chromium and the file download and not open in the browser.
Comment 120 David Bruant 2013-03-14 09:11:09 PDT
(In reply to Amiad from comment #119)
> I checked this on Chromium and the file download and not open in the browser.
It is its own issue. Could you file a new bug, please? That will allow the spec/implementation investigation to happen in this new bug instead of this one.
Thanks Amiad :-)
Comment 121 Boris Zbarsky [:bz] (still a bit busy) 2013-03-14 10:06:05 PDT
> I checked this on Chromium and the file download and not open in the browser.

Yes, Chromium implements @download quite differently from us once you start testing the edge cases.  Not least because the spec is ... lacking.
Comment 122 sys.sgx 2013-03-14 10:20:14 PDT
Yep, file a new bug for this one. It's not a spec issue, it's a browser way to handle content. As mentioned, FF tries to "play" this media file, so there should be a rule that will override this process when the link is inside the download attribute.
Comment 123 Boris Zbarsky [:bz] (still a bit busy) 2013-03-14 10:24:06 PDT
> FF tries to "play" this media file

Because the server _explicitly_ tells it to, by sending "Content-Disposition: inline".  The open spec question is whether that should or shouldn't override the download attribute.  In our implementation, a server-provided Content-Disposition header always wins.

Note that the spec does not define a specific processing model for @download in terms of whether the download actually happens, so both our behavior and Chrome's are spec-compliant.
Comment 124 Boris Zbarsky [:bz] (still a bit busy) 2013-03-14 10:25:08 PDT
Though the spec _does_ define what should happen when the @download filename and the Content-Disposition filename don't agree and you're downloading: the Content-Disposition filename wins.
Comment 125 sys.sgx 2013-03-14 11:53:07 PDT
Nice, thx for letting us know, then it's a fixed topic. :)
Comment 126 Jean-Yves Perrier [:teoli] 2013-03-15 00:54:33 PDT
I've edited the MDN documentation with this two bits of information (priority to C-D filename according the spec + spec silent with C-D:inline and this attribute, with different implementations across browsers. See: https://developer.mozilla.org/en-US/docs/HTML/Element/a
Comment 127 Jonas Sicking (:sicking) No longer reading bugmail consistently 2013-03-16 05:21:53 PDT
IMO the @download attribute should win both when it comes to what filename to use, and when it comes to using "inline" or "attachment" behavior.

People generally have an easier time getting markup right than getting headers right. That's one of the main reasons we have the @download attribute at all.
Comment 128 John Drinkwater (:beta) 2013-03-16 08:41:43 PDT
I’d also encourage @download to override C-D header, as a servers behaviour changing would negatively affect static pages.
Comment 129 Boris Zbarsky [:bz] (still a bit busy) 2013-03-16 14:17:17 PDT
If you want the spec to change, please raise spec issues.
Comment 130 gooddanny 2013-03-16 16:44:56 PDT
the header is better.its a cross browser solution, it works on ie.if people need use  download attribute, I think its  fine to spend a  little time to learn it.
Comment 131 gooddanny 2013-03-16 16:46:35 PDT
the header is better.its a cross browser solution, it works on ie.if people need use  download attribute, I think its  fine to spend a  little time to learn it.
Comment 132 Stefan Kienzle 2013-03-28 03:59:45 PDT
The problem mentioned in comment #116 (exit fullscreen mode) is getting better.
The fullscreen still remains but if you close the save dialog the message "xyz.com is now fullscreen ..." appears.
I think the problem is that the firefox main window gets the focus back after closing the save dialog. This message also appears if you switch to another app and go back to fullscreen firefox window.

Tested with firefox nightly 22.0a1 (2013-03-27) on Window 7.
Comment 133 panzi 2013-04-01 10:26:32 PDT
Well, now I can detect download attribute support ("download" in document.createElement("a")), but it will still not work for my use case, so I present the user a broken UI.

What I do:
I wrote a media player like interface for magnatune.com. On the album info page I present the user with download links to the songs (if they are signed-in). I use <a download="" ...> but the Ogg versions of the tracks still start to play in Firefox (20.0b7, 21.0a2, 22.0a1 on Linux x86_64 and 20 beta on Android ARM). Firefox 20 beta for Android even does nothing for the m4a and mp3 versions (shows a new about:blank tab) but it indeed downloads the wav version.

E.g. see (if you have a Magnatune account):
http://greattuneplayer.jit.su/#/album/Bootstrap%20Physics

Is there any other way to force a download? Maybe via some app-only API?
Comment 134 panzi 2013-04-01 10:32:25 PDT
Ah and Magnatune doesn't send a Content-Disposition header:

HTTP/1.1 206 Partial Content
Date: Mon, 01 Apr 2013 16:46:34 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Sun, 24 Feb 2013 00:41:47 GMT
Etag: "a5004f5-4d7f43-4d66db07da64d"
Accept-Ranges: bytes
Content-Length: 4836603
Content-Range: bytes 242248-5078850/5078851
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: audio/ogg
Comment 135 Boris Zbarsky [:bz] (still a bit busy) 2013-04-01 10:41:32 PDT
_If_ those are the headers that get sent, it should work.

Please file a bug with usable steps to reproduce (e.g. directions on getting a test magnatune account or a way to reproduce without) or at least an HTTP log of the interaction.
Comment 136 panzi 2013-04-01 10:55:00 PDT
I copied these headers with Firebug. Using curl (which doesn't do a range request) I get:

curl -I 'http://panzi:******@download.magnatune.com/music/Paul%20Avgerinos/Lovers/01-In%20My%20Arms-Paul%20Avgerinos.ogg'

HTTP/1.1 200 OK
Date: Mon, 01 Apr 2013 17:34:18 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Sun, 27 Jan 2013 00:43:05 GMT
ETag: "a50061f-48d1cc-4d43a718b7840"
Accept-Ranges: bytes
Content-Length: 4772300
Content-Type: audio/ogg

Which still has no Content-Disposition. It's a static HTTP server using HTTP Basic Auth. (no SSL/TLS) Maybe the HTTP Auth stuff throws Firefox off? I had to implement something like 4 different workarounds (different browsers and versions thereof) to create a "login" feature for an other domain that uses HTTP Auth so one can play the member "streams".

But I'll file a bug later (maybe not until tomorrow evening).
Comment 137 Boris Zbarsky [:bz] (still a bit busy) 2013-04-01 10:59:50 PDT
If you're seeing a range request, that's already way past the point where @download matters.  Hence my request for an actual HTTP log, which would show everything going back and forth, not just a quote from some later irrelevant part of the log...

But in any case, comment 136 has the info needed: that's a cross-site load, and we don't allow forcing downloads cross-site.  No need for a separate bug.
Comment 138 bartosztuszynski 2013-04-01 12:37:49 PDT
There is a problem with downloading a file when it extension is „js”, and URI scheme is „data:”, and operating system is Windows.

For example, when I clicked on any of the hyperlinks:

<a href="data:application/javascript,alert('Hello')" download="hello.js">Download</a>, 
<a href="data:application/javascript;base64,YWxlcnQoJ0hlbGxvJyk=" download="hello.js">Download</a>,
<a href="data:text/plain,alert('Hello')" download="hello.js">Download</a>

file is not saved in destination directory, but is displayed in Firefox's download manager.

This problem occurs in Firefox Nightly 22.0a1 (2013-03-30) for Windows 7 (64-bit), and for Windows XP (32-bit), but not for Ubuntu (64-bit).
Comment 139 panzi 2013-04-01 12:49:27 PDT
(In reply to Boris Zbarsky (:bz) from comment #137)
> But in any case, comment 136 has the info needed: that's a cross-site load,
> and we don't allow forcing downloads cross-site.  No need for a separate bug.

I see. Then I'll blacklist Gecko based browsers in my app. Why would I need this download attribute if I host the file myself? (except for data and object URLs) If the file is hosted on my domain I could change Content-Disposition.
Comment 140 Boris Zbarsky [:bz] (still a bit busy) 2013-04-01 13:04:01 PDT
> Why would I need this download attribute if I host the file myself?

Because lots of people apparently can't change content-disposition.

But yes, the point of this attribute is mostly for data and blob urls!
Comment 141 Stefan Kienzle 2013-05-17 01:35:08 PDT
Any updates on comment 132? This bug still exists in firefox nightly 24.0a1 (2013-05-16).
Comment 142 Masatoshi Kimura [:emk] 2013-05-17 01:42:41 PDT
Please file a separate bug. Totally unrelated with the download attribute.
Comment 143 Jean-Yves Perrier [:teoli] 2013-08-06 01:12:58 PDT
I've added a link to window.URL.createObjectURL in the doc of HTMLAnchorElement.download. With this I think we are done! :-)
Comment 144 Jonas Sicking (:sicking) No longer reading bugmail consistently 2013-08-13 15:50:57 PDT
FWIW, according to the spec editor, the spec specifies that

<a download href="someurl.html">

should bring up a dialog even when someurl.html returns with

Content-Disposition: inline; filename="B.txt"
or
Content-Disposition: inline


However in both cases the filename "someurl.html" should be the suggested name.


It's unclear if the spec always defined things that way, but it doesn't really matter, it's the behavior specified now.

If this is not the current behavior in Firefox, it would be great if someone could file a separate bug on that.
Comment 145 James Donohue 2013-08-21 12:09:34 PDT
I'm sorry to bring this up again regarding cross-origin a@download links:

The case against allowing cross-origin downloads is centered around the premise that visitors of an [evil] site (eg, discountipads.com) could unknowingly download a file from a site containing their own personal information (eg, gmail.com) and save it to their disk using a misleading name (eg, "discount.coupon") AND THEN proceed to another malicious page where they manually upload that same file they just downloaded. This is quite far-fetched in my opinion, and anyone who would succumb to such trivial trickery perhaps does not belong online in the first place. I mean c'mon...Click here to download our special discount offer and then re-upload it through our special form! Seriously? Download our special offer and then email it to this Yahoo address for a big discount! Do the people who fall for these things even know how to do email attachments?

I'm all for browser security, but if the good people of Chromium have no problem with this I don't see why Firefox has to completely banish it. At the very least I'd like to see a preference in about:config to enable cross-origin @download for "advanced" users (default it to false). Even better would be a confirmation box similar to: "Although this page is encrypted, the information you submit through this form won't be" or: "This page is requesting to install addons" or: "Files downloaded from the web may harm your computer" or even: "The security certificate of this page is invalid" ...y'know what I mean? There are myriad ways to heighten the user's awareness and inform them this might not be safe. One extra click and a short (or long?) delay is enough to let them assess the risk.

As the web grows, and the use of CDNs grows, and the presence of advanced web-apps grows, and the need to manage files hosted across servers grows, features like @download will become more important. And when a browser like Chrome supports it fully whereas Firefox does not, this is not a win for Firefox.

In short, I think that mitigating the potential evil uses of @download by simply ignoring the attribute in cross-origin scenarios is a woefully ill-thought move. I'm not saying the risk is entirely non-existent, quite the contrary: I am saying there are plenty of risky things one does online in the course of his day...downloading ANY file is high among them. Why not work around that issue with a well-thought user experience?
Comment 146 Javier España 2013-09-12 07:23:24 PDT
One issue I notice that doesn't happen in Chrome (which also supports the "download" attribute) is that on Firefox it currently doesn't work with "jpg" files.

So if you have:

<a href="test.jpg" download="test.jpg">Text here</a>

Instead of bringing up the download dialog it just opens the image in the browser. That's really not the desired behavior at all.

Javier
Comment 147 Boris Zbarsky [:bz] (still a bit busy) 2013-09-12 08:17:33 PDT
Javier, http://web.mit.edu/bzbarsky/www/testcases/download-attribute/test-jpeg-download.html works just fine for me.  Presumably there is more going on with your testcase (e.g. is your server sending explicit "Content-Disposition: inline" headers?).
Comment 148 Javier España 2013-09-12 08:28:40 PDT
How can I check that? Not sure what that is really, but the test case you sent works correctly...
Comment 149 Boris Zbarsky [:bz] (still a bit busy) 2013-09-12 09:03:22 PDT
> How can I check that?

Look at the HTTP headers in your server's response?
Comment 150 Javier España 2013-09-12 09:11:12 PDT
That doesn't seem to be the issue, according to this site http://http-headers.online-domain-tools.com/

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.4; JBoss-4.3.0.GA_CP01 (build: SVNTag=JBPAPP_4_3_0_GA_CP01 date=200804211657)/Tomcat-5.5
responseHasData: true
Content-Type: text/html;charset=utf-8
Vary: Accept-Encoding
Content-Encoding: gzip
Cache-Control: max-age=14400
Date: Thu, 12 Sep 2013 16:10:08 GMT
Content-Length: 13
Connection: keep-alive
Comment 151 Boris Zbarsky [:bz] (still a bit busy) 2013-09-12 09:25:09 PDT
OK.  Then, assuming that's a same-origin link, it should work.  Do you have a link to a non-working testcase?
Comment 152 Javier España 2013-09-12 09:28:54 PDT
Well, I don't. The environment is on local so I can't share a link. Could that be the issue maybe?
Comment 153 Boris Zbarsky [:bz] (still a bit busy) 2013-09-12 09:47:57 PDT
Unless you mean it's a file:// URI, no.

You could try creating a log using https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/HTTP_logging#Logging_HTTP_activity and attaching it here, just in case the headers we see are different from what the tool from comment 150 was showing you...

Also, worth making sure you don't have any extensions interfering.
Comment 154 Javier España 2013-09-12 10:55:21 PDT
In a while I'll go to another stating, I'll test it there and let you know if it's solved. Thanks for the help so far :)
Comment 155 KOLANICH 2015-03-08 07:44:50 PDT
>When the user clicks such a link, the user will be prompted if they want to download. It seems very easy for the user to make the mistake of thinking that something on the original website is being downloaded, and not something from bank.com.

1 why are you thinking that is a security issue? The FF download dialog displays the domain and protocol to help user understand from where file is downloaded and make right decision
2 We can additionally display warning that download was forced by referrer page, not the http header.
3 Also we can check CORS http headers.
Comment 156 Boris Zbarsky [:bz] (still a bit busy) 2015-03-08 17:16:13 PDT
You may want to read the discussion in bug 676619.
Comment 157 Jonas Sicking (:sicking) No longer reading bugmail consistently 2015-04-03 10:20:29 PDT
Please open a new bug if you think we should loosen the same-origin restriction.

I'll leave the decision up to the security team, so probably cc dveditz and :sworkman

Note You need to log in before you can comment on or make changes to this bug.