Closed Bug 681140 Opened 13 years ago Closed 13 years ago

josiasdesouza.folha.blog.uol.com.br - Corrupted Content error due to multiple Content-Disposition header field instances, new in Firefox 7

Categories

(Tech Evangelism Graveyard :: Portuguese, defect)

defect
Not set
critical

Tracking

(firefox6 unaffected, firefox7+ affected, firefox8 affected)

RESOLVED FIXED
Tracking Status
firefox6 --- unaffected
firefox7 + affected
firefox8 --- affected

People

(Reporter: christian, Unassigned)

References

(Blocks 1 open bug, )

Details

(Keywords: dev-doc-needed, relnote)

Found on twitter and mozillazine (http://forums.mozillazine.org/viewtopic.php?f=23&t=2284289):

This site works on Fx6 but not on 7b1: josiasdesouza.folha.blog.uol.com.br

On 7.0b1 you get a corrupted content error page. I just tried it in the mozilla offices and see the correct page on 6 but get the error on 7b1 (and Aurora and Nightly)
The response headers contain:

Location: http://josiasdesouza.folha.blog.uol.com.br/index.html
Location: http://josiasdesouza.folha.blog.uol.com.br/

The location response header is defined as having a single absolute URL, so that response is non-sensical. But that's not why it's suddenly rejected - we do that because it matches the signature of a variation of a CRLF injection attack. See 655389.

For security reasons, they need to fix their server.
Blocks: 655389
Patrick, are you willing to get in touch with them about this?
(In reply to Boris Zbarsky (:bz) from comment #2)
> Patrick, are you willing to get in touch with them about this?

That's not going to be me because the website is in portugese, which I don't speak. I can't find an email or general support form either - just some phone numbers in Brazil.
Fernando, Marcio, can you help out here?
I'm assuming we can close this while still going forward with the outreach--there's nothing to fix in our code.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → INVALID
> I'm assuming we can close this while still going forward with the outreach

Actually, the right way to do that is to move this to the right product.
Assignee: nobody → portuguese
Status: RESOLVED → REOPENED
Component: Networking → Portuguese
Product: Core → Tech Evangelism
QA Contact: networking → portuguese
Resolution: INVALID → ---
Version: 7 Branch → unspecified
this bug also happens while connecting to any device via wifi,since ffb7
I wonder if certain captive portals or wifi devices change the headers not quite the right way.
(In reply to Chango from comment #7)
> this bug also happens while connecting to any device via wifi,since ffb7

(In reply to [:Cww] from comment #8)
> I wonder if certain captive portals or wifi devices change the headers not
> quite the right way.

This bug is about the response headers produced by josiasdesouza.folha.blog.uol.com.br
 and is assigned to evangelism.

If your comments are about something else, then please file them under their own bug along with appropriate details. The comment about *any* device via wifi is not true - I have many counter examples.
No longer blocks: 655389
Depends on: 655389
process nit: this bug "blocks" bug 655389 rather than the other way around because if we take that patch on stable branches we'll need to deal with the regression.
Blocks: 655389
No longer depends on: 655389
I had the same issue on my website.  After some debugging I found out how to fix it.

I removed "$r->headers_out->{'Content-Length'} = $file_size;" from my code.  Seems to have something to do with the Content-Length header.
(In reply to Tim Hibbard from comment #11)
> I had the same issue on my website.  After some debugging I found out how to
> fix it.
> 
> I removed "$r->headers_out->{'Content-Length'} = $file_size;" from my code. 
> Seems to have something to do with the Content-Length header.

Yes. Probably the code was causing *two* instances of the header to be sent. This is exactly why it's good for the browser to warn.
(In reply to Tim Hibbard from comment #11)
> I had the same issue on my website.  After some debugging I found out how to
> fix it.
> 
> I removed "$r->headers_out->{'Content-Length'} = $file_size;" from my code. 
> Seems to have something to do with the Content-Length header.

that should mean you were publishing 2 content-length headers with different values. in addition to being a response-smuggling attack signature it will lead to random framing errors when interacting with your website because one of them, by definition, was wrong.
(In reply to Julian Reschke from comment #12)
> (In reply to Tim Hibbard from comment #11)
> > I had the same issue on my website.  After some debugging I found out how to
> > fix it.
> > 
> > I removed "$r->headers_out->{'Content-Length'} = $file_size;" from my code. 
> > Seems to have something to do with the Content-Length header.
> 
> Yes. Probably the code was causing *two* instances of the header to be sent.
> This is exactly why it's good for the browser to warn.

(In reply to Julian Reschke from comment #12)
> (In reply to Tim Hibbard from comment #11)
> > I had the same issue on my website.  After some debugging I found out how to
> > fix it.
> > 
> > I removed "$r->headers_out->{'Content-Length'} = $file_size;" from my code. 
> > Seems to have something to do with the Content-Length header.
> 
> Yes. Probably the code was causing *two* instances of the header to be sent.
> This is exactly why it's good for the browser to warn.

(In reply to Julian Reschke from comment #12)
> (In reply to Tim Hibbard from comment #11)
> > I had the same issue on my website.  After some debugging I found out how to
> > fix it.
> > 
> > I removed "$r->headers_out->{'Content-Length'} = $file_size;" from my code. 
> > Seems to have something to do with the Content-Length header.
> 
> Yes. Probably the code was causing *two* instances of the header to be sent.
> This is exactly why it's good for the browser to warn.

(In reply to Julian Reschke from comment #12)
> (In reply to Tim Hibbard from comment #11)
> > I had the same issue on my website.  After some debugging I found out how to
> > fix it.
> > 
> > I removed "$r->headers_out->{'Content-Length'} = $file_size;" from my code. 
> > Seems to have something to do with the Content-Length header.
> 
> Yes. Probably the code was causing *two* instances of the header to be sent.
> This is exactly why it's good for the browser to warn.

This is perl code but it should not matter .. rather self readable.  However I do not think I was calling *two* instances of the header to be sent ... maybe I am wrong though.  I admit I know little of http headers however commenting out Content-Length fixed the problem.

$r->headers_out->clear();
$r->no_cache(0);
$r->headers_out->{'Content-Disposition'} = "attachment;filename=\"$file_name\"";

#$r->headers_out->{'Content-Length'} = $file_size;

$r->headers_out->{'Content-Type'} = $file_type;
open(FILE,$file_location);
while(<FILE>){
     print $_;
}
close(FILE);
(In reply to Tim Hibbard from comment #14)
> This is perl code but it should not matter .. rather self readable.  However
> I do not think I was calling *two* instances of the header to be sent ...
> maybe I am wrong though.  I admit I know little of http headers however
> commenting out Content-Length fixed the problem.
> 
> $r->headers_out->clear();
> $r->no_cache(0);
> $r->headers_out->{'Content-Disposition'} =
> "attachment;filename=\"$file_name\"";
> 
> #$r->headers_out->{'Content-Length'} = $file_size;
> 
> $r->headers_out->{'Content-Type'} = $file_type;
> open(FILE,$file_location);
> while(<FILE>){
>      print $_;
> }
> close(FILE);

It depends on what runs the code. Usually, the server framework is responsible for message-level header fields, so it will set Content-Length itself (of course it should then prevent the script code to set it as well).
(In reply to Julian Reschke from comment #15)

> It depends on what runs the code. Usually, the server framework is
> responsible for message-level header fields, so it will set Content-Length
> itself (of course it should then prevent the script code to set it as well).

Also worth noting - those two things set it to different values. If it was a pure duplicate we would have ignored it. (confirm with redbot?)
We should create a document on MDN and/or SUMO that is easily found when searching for "NS_ERROR_CORRUPTED_CONTENT" via Google, that says that this error occurs when the server response has multiple, conflicting values for the Content-Length, Content-Disposition, and/or Location headers. The article should suggest to the developer that he change his server so that it emits only one value for these header fields. I filed bug 688345 for logging the error into the web console. Once that is done, the MDN/SUMO article(s) can explain how to use the web console to diagnose and fix the issue.
Keywords: dev-doc-needed
I had this issue to today and nothing inside FF would let me debug this (seams like a big in itself)

My headers:
HTTP/1.1 200 OK
Date: Thu, 29 Sep 2011 01:26:49 GMT
Server: Apache
Content-Disposition: inline; filename="honda_65x44.png"
Cache-Control: maxage=3600
Expires: Thu, 29 Sep 2011 02:26:49 GMT
Content-Length: 2945;
Content-Type: image/png

It worked once I removed the ; from the end of content-length. It's not just about duplicate headers, its any vary minor error in the headers.
scotepi, that's a separate issue from this bug.  Would you mind filing it as a separate bug and adding me to the cc list?
Hello there the same error when I want to download mp3 file
File is downloaded in all browsers except firefox 7

Server response:

      Server[nginx/1.0.1]
      Date[Thu, 29 Sep 2011 11:54:19 GMT]
      Content-Type[application/octetstream]
      Connection[keep-alive]
      Content-Length[7574592]
      Last-Modified[Tue, 08 Feb 2011 03:31:07 GMT]
      Cache-Control[must-revalidate, post-check=0, pre-check=0]
      Content-Disposition[attachment; filename="UMG_audtrk_00602527626604_01_001_67.mp3", attachment; filename=Let_England_Shake.mp3]
      Expires[Thu, 29 Sep 2011 11:54:19 GMT]
      Accept-Ranges[bytes]
(In reply to Andrey from comment #21)
> Hello there the same error when I want to download mp3 file
> File is downloaded in all browsers except firefox 7
> 

can you please supply the url, or run the url through redbot.org and report what it says?

(the response headers you show are post processed, and we need to see the original version - but I'm betting the issue is with Content-Disposition)
http://universal.enaza.ru/download/USUM71108417?downloadfile=Introbra.mp3

  HTTP/1.1 200 OK
    Server: nginx/1.0.1
    Date: Thu, 29 Sep 2011 13:01:38 GMT
    Content-Type: application/octetstream
    Connection: keep-alive
    Content-Length: 3229906
    Last-Modified: Wed, 06 Jul 2011 09:26:54 GMT
    Cache-Control: must-revalidate, post-check=0, pre-check=0
    Content-Disposition: attachment;
        filename="UMG_audtrk_00602527747019_01_001_67.mp
        3"
    Expires: Thu, 29 Sep 2011 13:01:38 GMT
    Accept-Ranges: bytes
    Content-disposition: attachment; filename=Introbra.mp3
(In reply to Andrey from comment #23)
> http://universal.enaza.ru/download/USUM71108417?downloadfile=Introbra.mp3
> 

yep - double CD header. The current feeling on that is that it poses a security problem.
(I preferred the PJ Harvey MP3).

(In reply to Patrick McManus from comment #24)
> (In reply to Andrey from comment #23)
> > http://universal.enaza.ru/download/USUM71108417?downloadfile=Introbra.mp3
> > 
> 
> yep - double CD header. The current feeling on that is that it poses a
> security problem.

Usually I'm happy with draconian.

However, I do not agree that there's really a security risk to address here. The C-D information is inconsistent, and IMHO it would be totally OK to just ignore it. (In which case the content would be delivered without attachment and filename info, potentially playing in the browser).

Also, we *are* a bit inconsistent in that we handle

  C-D: value1
  C-D: value2

differently from

  C-D: value1, value2

which according to the specs is equivalent. I think both cases should be handled by just ignoring the C-D header field(s).
Thank you corrected the title and it worked.
> 
> Also, we *are* a bit inconsistent in that we handle
> 
>   C-D: value1
>   C-D: value2
> 
> differently from
> 
>   C-D: value1, value2
> 
> which according to the specs is equivalent.

I know.

but they aren't equivalent on this internet thang. In a response smuggling attack an attacker can inject either one of those headers due to server bugs.

It does seem to me that being able to change the default save name for a download might have some security implications, but I'm not the person who decided that was a problem for content-disposition. I'm not a C-D expert, nor do I want to be. I made that judgment specifically for Content-Length, and I stand by that one.

it would be great for you and bz and jduell to sort out what the behavior of CD specifically should be. Maybe your suggesting that a CD conflict should not throw the error, but rather zero-out the header is a good way forward.
(In reply to Patrick McManus from comment #27)
> I know.
> 
> but they aren't equivalent on this internet thang. In a response smuggling
> attack an attacker can inject either one of those headers due to server bugs.

Understood. But if the message, after the injection, went through an intermediate that folds multiple headers into one (which is allowed), we will only see a single header field instance using the command notation.

> It does seem to me that being able to change the default save name for a
> download might have some security implications, but I'm not the person who
> decided that was a problem for content-disposition. I'm not a C-D expert,
> nor do I want to be. I made that judgment specifically for Content-Length,
> and I stand by that one.

And I totally agree with the outcome for that one!

> it would be great for you and bz and jduell to sort out what the behavior of
> CD specifically should be. Maybe your suggesting that a CD conflict should
> not throw the error, but rather zero-out the header is a good way forward.

Sounds reasonable to me.
(updated the title so it mentions C-D)
Summary: Corrupted Content error, new in Firefox 7 → Corrupted Content error due to multiple Content-Disposition header field instances, new in Firefox 7
Blocks: 609667
See also 480100.
OS: Mac OS X → All
Looks like this happens often.  Could we have some smarter logic for duplicated Content-Disposition?

E.g: if all are "attachment" and all result to the same extension, take the first/last one; otherwise, throw the corrupted content error.  The same for merged values.


This problem is young, however.  We first may want to see how fast and willingly web admins fix the issue on their sides.
OS: All → Mac OS X
OS: Mac OS X → All
> Could we have some smarter logic for duplicated Content-Disposition?

Well, yes and no.

"Yes" in that we could return to merging the headers, and implement some smarter detection logic (note that I--and most probably bz--would want any evidence of a duplicated CD header to indicate 'attachment', certainly if that value appears at any point in the header: we can't allow later headers to redefine attachment -> inline, or we have a security risk).

"No" in that the cat is out of the bag:  this is now shipped in FF7, and we can't really take it back.  I suspect that however much pain this causes (for which I'm very sorry!), it's likely to be fixed by sysadmins within the 12-16 weeks we'd need to ship different logic.
bz/scotepi:  Re: comment 19.  That's bug 683699.  We have a one-line patch, but the same issue with whether we want to fix it, and whether it's worth it given that's it's landed in FF 7.
They fixed the pages at Folha.com (http://www1.folha.uol.com.br/blogs/).

For me, this is solved.

Thanks you.
Hello,

I own a small printserver LN-308 from Sitecom.
Trying to access its config page with FF7 leads to the same error.

Regards.
Laurentwb, could you please file a separate bug, add me to the cc list on it, and attach the response headers from your config page to it?  I doubt that you're running into this exact issue; the error can occur for a number of reasons.
First of all, this problem newly appears with Firefox 7 (not with Firefox 6 or Internet Explorer). Some Mozilla engineers argue that this is not a bug, that Firefox 7 is now doing the right thing, and all servers in the world should change their codes. I feel that attitude is unreal and irresponsible.

I think I have a solution for Abyss servers, and it is really simple.

Log in to your Abyss Web Server Console (127.0.0.1:9999)

Press "Configure", "General", "Advanced Parameters", Press "Edit".

In "Disable Caching Negotiation for", press "Add", type "*" in the box for Virtual Path (no need to press "Browse"). Press "OK".

Press "OK" a few times to go back to Console. Press "Restart" to apply the configuration changes.

Then Firefox 7 is pleased.

Remark: Abyss is also to be blamed because it sends the HTTP Header "Content-Length" two times erroneously, but this oddity used to be tolerated.
John, I'd highly suggest you re-read comment 13 and comment 32 here.

This bug, as filed, is FIXED, per comment 34.
Status: REOPENED → RESOLVED
Closed: 13 years ago13 years ago
Resolution: --- → FIXED
Summary: Corrupted Content error due to multiple Content-Disposition header field instances, new in Firefox 7 → josiasdesouza.folha.blog.uol.com.br - Corrupted Content error due to multiple Content-Disposition header field instances, new in Firefox 7
(In reply to John Loo from comment #37)
> First of all, this problem newly appears with Firefox 7 (not with Firefox 6
> or Internet Explorer). Some Mozilla engineers argue that this is not a bug,
> that Firefox 7 is now doing the right thing, and all servers in the world
> should change their codes. (...)

You may be interested in http://code.google.com/p/chromium/issues/detail?id=103618 - translation: Chrome 16 is doing this as well, but is even more picky.
Alright.

1. The aim of a browser (Firefox or Chrome) should never be to be fault-finding with the server, but to be tolerant and accommodating, and show web pages to the end-user as far as it is possible, without the risk of security and abude.

2. A layman would never know what to do when FF7 gives that strange reject message. I think they will switch back to FF6 or use IE.

3. If FF7 is so correct, then tell me why ... whenever it says "The page you are trying to view cannot be shown", you can press "Back" to the previous page, and then press "Forward" to the offending page, and now it now has no problem and can be shown beautifully in FF7?

Regards,
John
(In reply to John Loo from comment #40)

> 
> 3. If FF7 is so correct, then tell me why ... whenever it says "The page you
> are trying to view cannot be shown", you can press "Back" to the previous
> page, and then press "Forward" to the offending page, and now it now has no
> problem and can be shown beautifully in FF7?
> 

hmm.. that sounds like a cache bug actually.
Let us put this in focus.

The offending header (in the case of Abyss) says:

Content-Type: text/html
Content-Length: 
Connection: Keep-Alive
Keep-Alive: timeout=150000, max=10
Date: Sat, 27 Aug 2011 14:21:26 GMT
Server: Abyss/2.6.0.0-X1-Win32 AbyssLib/2.6.0.0
Content-Length: 

So you can see, "Content-Length" is given twice. But it is a simple matter to ignore HTTP headers which are empty? Are there any security risks? Not that I can see.

Engineers who stick to doing it by the book, and reject to show this page ... should be praised?
> Are there any security risks?

For ignoring headers in general, yes.

But it seems to me that accepting a duplicated header with the same value should not have security risks.  Patrick, could we do that?
(In reply to John Loo from comment #42)
> Let us put this in focus.
> 
> The offending header (in the case of Abyss) says:
> 
> Content-Type: text/html
> Content-Length: 
> Connection: Keep-Alive
> Keep-Alive: timeout=150000, max=10
> Date: Sat, 27 Aug 2011 14:21:26 GMT
> Server: Abyss/2.6.0.0-X1-Win32 AbyssLib/2.6.0.0
> Content-Length: 
> 
> So you can see, "Content-Length" is given twice. But it is a simple matter
> to ignore HTTP headers which are empty? Are there any security risks? Not
> that I can see.

Yes, there are. Content-Length is important at it's used to delimit the messages in the stream. If different recipients and intermediates disagree about what the message length is, they'll *also* disagree about what the *next* message is. Google for "HTTP rersponse smuggling".
 
> Engineers who stick to doing it by the book, and reject to show this page
> ... should be praised?

Absolutely.
(In reply to Boris Zbarsky (:bz) from comment #43)
> > Are there any security risks?
> 
> For ignoring headers in general, yes.
> 
> But it seems to me that accepting a duplicated header with the same value
> should not have security risks.  Patrick, could we do that?

For content-length we do accept duplicated headers with the exact same legitimate value.

In this case it is not a legitimate value.

Indeed, what would the length of the above response be? Pretending it wasn't there would mean read to EOF, but the server is obviously trying to delimit. The server also says keep-alive and EOF doesn't make any sense with keep-alive. If it is trying to do K-A and we read to EOF the result would just be a hang.

The truth is that response in comment 42 is unintelligable spew instead of http. imo.making guesses about what that means is a good way to end up with a security problem - which is what drove the change.

I have much more sympathy for the cases like "Content-Length: 100;" where we reject it due to the semi-colon. We could be more tolerant there.

perhaps railing against the server which is generating the invalid sequence would be more effective?
> making guesses about what that means is a good way to end up with a security problem

Accepted, but what did we use to guess before?
-1 (i.e. no CL).

(In reply to Boris Zbarsky (:bz) from comment #46)
> > making guesses about what that means is a good way to end up with a security problem
> 
> Accepted, but what did we use to guess before?
(In reply to John Loo from comment #42)

> Engineers who stick to doing it by the book, and reject to show this page
> ... should be praised?

Yes, and if you disagree, please file a separate bug against Core, since this one is FIXED and such discussion is not relevant here.

(In reply to Patrick McManus from comment #41)
> (In reply to John Loo from comment #40)
> 
> > 
> > 3. If FF7 is so correct, then tell me why ... whenever it says "The page you
> > are trying to view cannot be shown", you can press "Back" to the previous
> > page, and then press "Forward" to the offending page, and now it now has no
> > problem and can be shown beautifully in FF7?
> > 
> 
> hmm.. that sounds like a cache bug actually.

Yeah, that should probably be filed separately, too.
Product: Tech Evangelism → Tech Evangelism Graveyard
You need to log in before you can comment on or make changes to this bug.