Closed Bug 300613 Opened 19 years ago Closed 19 years ago

insecure page can be made to appear secure

Categories

(Core :: Security, defect)

x86
All
defect
Not set
major

Tracking

()

VERIFIED FIXED
mozilla1.8rc1

People

(Reporter: matt_cooley, Assigned: darin.moz)

References

(Blocks 1 open bug, )

Details

(Keywords: fixed1.8, helpwanted, Whiteboard: [sg:fix])

Attachments

(6 files, 2 obsolete files)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4 If a non-SSL site redirects a user to an SSL site which responds with a certificate but doesn't respond with content (such as apache-ssl with broken gcache), Firefox will keep the non-SSL content on the browser page, but add a lock. This gives the appearance that an insecure page can be trusted. Clicking on the lock causes Firefox to state that the non-SSL site supports authentication and is verified by the CA of the SSL site. Reproducible: Always Steps to Reproduce: 1. Setup an SSL server (tested on Debian) using apache-ssl. In httpd.conf, add the line: SSLCacheServerPort 1234 Run apache-ssl and kill the gcache process. Connecting to the site using curl or openssl should show the site answering and neogiating with a certificate, but the connection will close immediately afterward. 2. Put up a page on a secondary web server (non-SSL) with the following line: <META HTTP-EQUIV=Refresh CONTENT="0; URL=https://apache-sslserver"> where apache-sslserver is the address to the SSL server setup in step 1. Add other content to the page (i.e. "This resides on a non-SSL server") 3. Open Firefox 1.0.4 on Windows XP and go to the address "http://nonsslserver/page" where nonsslserver is the address of the secondary server and specify the page created in step 2. Actual Results: Observe that a lock will appear in the browser but the address and content of the site will be that of the non-SSL server. Clicking on the lock will show that the non-SSL site supports authentication and the identity has been verified by the CA that signed the certificate of the SSL site. Expected Results: Return an error and redraw the browser window with no indication that the current site is secure. The bug can only be reproduced once before the browser has to be closed and restarted. Additional attempts to reproduce the behavior without first restarting the browser result in an error popup, "the connection has terminated unexpectedly".
Confirming bug, I see it with Mozilla Seamonkey 1.7.8 on Linux, too.
Severity: normal → major
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Windows XP → All
Product: Firefox → Core
Version: unspecified → Trunk
Blocks: lockicon
Matt, I see a worse behaviour. You said, it only works once for you in a browser session. The Linux version I'm playing with shows your bug every time.
Man, we can't seem to keep this thing fixed. This is like bug 238566 or bug 196827 or several others lock icon issues.
Whiteboard: [sg:fix]
Darin: can you help us figure out how we regressed this? Bob: can you help us narrow down the regression window for this on the trunk or branch?
Assignee: nobody → darin
Target Milestone: --- → mozilla1.8beta4
(In reply to comment #4) > Bob: can you help us narrow down the regression window for this on the trunk or > branch? I'll see what I can do about getting a test environment then look for the regression.
I just tried the testcase with Mozilla 1.7.10+ on Linux, and I no longer see the bug.
Target Milestone: mozilla1.8beta4 → mozilla1.8beta5
Flags: blocking1.8rc1?
any progress on finding what broke and when?
Nope. I have not had a chance to investigate this bug at all. Help would be appreciated.
Keywords: helpwanted
Dveditz, we need your help here. Can you investigate and help us come up with a fix?
Assignee: darin → dveditz
Matt, are you able to make your test site working again? It seems your site at https port 443 is now running a SSH server. With the current configuration, whatever browser I use, Firefox 1.0.4, 1.0.5, Mozilla 1.7.12, 1.8 beta or head of 1.9, I am not able to reproduce the bug.
I spent 30 minutes trying to set up a server that could allow me to reproduce the bug, but I'm not able to. The option you mention (SSLCacheServerPort 1234) seems to be supported by very old versions of Apache only, I installed a version 1.3.23 on my machine, it accepted the config option with a warning, I have SSL running on port 443, but I do not have a gcache process???
I reset the test case, so give it another try http://www.0x90.org/~txs/firefox (changed server from hackmatt to mattcooley) Also, regarding the change with apache-ssl 1.3.33 (this is the Debian package, other installs may vary) in httpd.conf, make sure the following lines are as such: # Set the global cache server port number, or path. If it is a path, a Unix # domain socket is used. If a number, a TCP socket. SSLCacheServerPort 1234 #SSLCacheServerPort /var/run/gcache_port Restart apache-ssl and gcache should be listening on port 1234
Attached file Logfile (deleted) —
Logfile, created using NSPR_LOG_MODULES=pipnss:5,nsSecureBrowserUI:5 What I can see is: - the HTTP channel code complains "No response head", I guess that means, no data is being received - nevertheless, OnStateChange gets called with a progress notification of nsIWebProgressListener::STATE_TRANSFERRING. The nsSecureBrowserUI uses this event to decide "document data has been received" - in addition, OnLocationChange gets called, and because of the assumption of data having been transfered, the UI gets updated.
Thanks Matt, your test case works again, and I am able to reproduce, with all recent versions.
QA Contact: firefox → toolkit
QA Contact: toolkit → firefox
Flags: blocking1.8rc1? → blocking1.8rc1+
I have a patch, it fixes the problem on trunk and on the 1.7 and 1.8 branches. With the patch applied, when connecting to the testcase, the URL bar remains at the URL of the displayed content, and the lock icon remains in insecure state. Darin, in this scenario, nsHttpChannel::OnStartRequest issues a warning NS_WARNING("No response head in OnStartRequest"); The code goes on to retry the connection, based on some error codes. When not retrying, the code goes on to call CallOnStartRequest, which seems to be responsible for sending out the STATE_TRANSFERRING event. My suggestion is, after having decided not to retry, we should retest whether headers have been received. If not, we should stop. I implemented the stop using a simple return NS_ERROR_FAILURE; This fixes the problem, but I can't tell if it will introduce regressions. Do you think it might?
Attached patch Patch v1 (obsolete) (deleted) — Splinter Review
Assignee: dveditz → kaie.bugs
Status: NEW → ASSIGNED
Attachment #199476 - Flags: review?(darinf)
This seems wrong to me. If a channel is in a failed state, then it still has to call OnStartRequest and OnStopRequest.
Comment on attachment 199476 [details] [diff] [review] Patch v1 This can't be the right fix.
Attachment #199476 - Flags: review?(darinf) → review-
Darin, do you think the STATE_TRANSFERRING event should be sent out, even if no data is being transferred? In that case, the security tracking needs to become more complex and filter out those events that carry a failure state. However, I checked member nsresult nsIRequest::status of the Request that is sent to OnStateChange, and it is 0 / NS_OK, despite nsSSLIOLayerConnect having returned a failure. Parameter aStatus passed to OnStateChange is NS_OK, too. Is it a bug that "status" does not indicate the error condition? Or is there another place to test the Request/Channel for a failure state?
> However, I checked member > nsresult nsIRequest::status > of the Request that is sent to OnStateChange, > and it is 0 / NS_OK, > despite nsSSLIOLayerConnect having returned a failure. > > Parameter aStatus passed to OnStateChange is NS_OK, too. > > Is it a bug that "status" does not indicate the error condition? Or is there > another place to test the Request/Channel for a failure state? Yes, that sounds like a bug. If NSS and PSM think that there was a data transfer error, then that error code should be reflected via nsIRequest::status and the status parameter passed to onStateChange. Then, the secure browser ui would do the right thing.
kai, what needs to happen here? We're running very short on time for the next release.
Darin, I was wrong, I said I see an error returned, but it the WOULD_BLOCK error code. Actually, no error is happening. It's just that SSL handshaking is working fine, but no data is being transfered at all. This has the effect that no error messages are being produced. So, my current opinion is: The document loading could detect that no data has been transfered, that we have received any secure data, and the notifications about transfered data and location change should be suppressed. My patch was a suggestion to suppress it based on having http headers received. But Darin did not like that patch. Unfortunately I don't understand the document loader internals well enough to come up with another suggestion at this point. Darin, with this new information, that no error message at the SSL level is being produced, do you have an idea how to change the document loader?
Matt, I'm having trouble again with your 2-part test case. The URL you gave above gives a "forbidden" error message. However, the "meat" of your test case currently works. The new intstructions to reproduce are: Go to any insecure site. Then open https://www.mattcooley.com
Nelson, FYI. I'm attaching a curl and ssltap output of the bug scenario. In short, SSL handshake seems to work fine, but directly afterwards the connection is closed, no application data is being received by the client. However, this partial success triggers the application to update the UI to the secure state. In my opinion, this is an application bug, and we should come up with a fix, either in the document loading logic or with PSM. But for completeness I would like to ask: Nelson, do you think the SSL communication should produce an error message in this special scenario? If I understand Darin correctly, an error message produced during SSL read/write communication, passed up via PSM to the document loader, could have the desired effect, to signal the problem.
Assignee: kaie.bugs → dveditz
Status: ASSIGNED → NEW
QA Contact: firefox → toolkit
(sorry I accidentially clicked reassign before clicking commit)
Attached patch Patch v2 (obsolete) (deleted) — Splinter Review
Here is another suggestion. I looked at the SSL debugging tool ssltap. When that tool detects a zero byte return value from PR_Read or PR_Write, it reports that as an EOF error. A SSL socket within Mozilla uses layered I/O code, where PSM provides an intermediate layer, before calling I/O functions in the SSL library (NSS). When PSM receives a zero byte return value from SSL read/write, no special action is done. It simply passes up that zero byte value, with no indication of an error. I also checked PR_GetError, but it's zero, the SSL library did not set an error code. Here is a patch, based on ssltap's behaviour. With that patch applied, if a zero byte value is returned by the SSL library, PSM I/O layer code sets error code PR_END_OF_FILE_ERROR and returns -1 as the byte count of the read/write function. This change makes Mozilla behave better than currently. In Matt's test case, Mozilla will bring up an error message "the connection has terminated unexpectedly", which is indeed what happens. And the lock remains in the insecure state. I tested this patch with other (good) SSL sites, and on first sight, it still seems to work. But again, I'm unsure whether this patch has negative side effects.
Attachment #199476 - Attachment is obsolete: true
Comment on attachment 200043 [details] [diff] [review] Patch v2 Darin, do you have thoughts on possible side effects? I wonder if a zero byte return value from read/write can ever be an allowed condition, where we should not abort (like this patch implements). Probably Nelson would have thoughts, too, but I emailed with him today, and he will be away for a couple of days.
Attachment #200043 - Flags: review?(darin)
NELSON sent the following comment to me by email: > I looked at the SSL debugging tool ssltap. > When that tool detects a zero byte return value from PR_Read or PR_Write, it > reports that as an EOF error. I would not say that SSLTAP reports every zero length return as an EOF *error*. I would say that SSLTAP reports every zero length return *from read* as EOF. That is, SSLTAP reports all EOFs, so that the human reading the output can tell when the remote client or server closed its socket. This does not always indicate an error. The receipt of EOF is usually not considered to be an error, which is why it is reported with zero length and not an error code. > A SSL socket within Mozilla uses layered I/O code, where PSM provides an > intermediate layer, before calling I/O functions in the SSL library (NSS). > > When PSM receives a zero byte return value from SSL read/write, no special > action is done. It simply passes up that zero byte value, with no indication of > an error. I also checked PR_GetError, but it's zero, the SSL library did not > set an error code. So, the question is: when EOF is received, when should it be reported as a mere ordinary non-erroneous EOF, and when should it be reported as an error? I believe the answer is that it is an error when a higher-level protocol receives an ordinary EOF indication from the layer below it, and determines that the connection should never be terminated while the protocol is in the then-current state. SSL returns the EOF error if/when a normal EOF is received from the TCP socket below, while the first SSL handshake is in progress and no SSL error alert has been received. SSL determines that the receipt of an EOF in the middle of a handshake, without receiving an error alert record, indicates that the remote party terminated the handshake improperly. So, in effect, the SSL library turns the receipt of an ordinary TCP EOF during the initial handshake into an SSL protocol EOF error. I think that the protocols above the (SSL or non-SSL) socket should similarly notice when an ordinary EOF is received from the layer below, and should then determine for themselves whether the termination of the underlying connection is acceptable or is a violation of their protocol. For example, if an http client (with or without SSL) sends an http request and gets back EOF instead of an http response, it is probably appropriate for the http client to change that ordinary EOF into an EOF error. But I think this must be done by the upper level (http) protocol code, because only that protocol knows when an EOF is an error, and when it is not. > Here is a patch, based on ssltap's behaviour. With that patch applied, if a > zero byte value is returned by the SSL library, PSM I/O layer code sets error > code PR_END_OF_FILE_ERROR and returns -1 as the byte count of the read/write > function. > This change makes Mozilla behave better than currently. In Matt's test case, > Mozilla will bring up an error message "the connection has terminated > unexpectedly", which is indeed what happens. And the lock remains in the > insecure state. > > I tested this patch with other (good) SSL sites, and on first sight, it still > seems to work. But again, I'm unsure whether this patch has negative side > effects. It appears to me that this patch turns every zero return value from read *or write* on an SSL socket into an error. This means that: 1) every EOF will now be an error. There will be no more ordinary EOFs. 2) zero-length writes (that is, write calls where the length requested to be written is zero) will now always return errors. (Without this patch, a zero length write will either return 0 for success or -1 for an error.) Zero length writes are used to drive handshakes on non-blocking sockets, and so they should not experience errors when the return value is also zero. In short, your patch makes PSM turn ordinary EOFs into EOF errors without knowledge of the higher layer's protocol state. I think the right way to deal with this is for the higher layer protocols to detect this invalid EOF condition and turn it into an error themselves.
Comment on attachment 200043 [details] [diff] [review] Patch v2 Based on Nelson's comment I'm obsoleting this patch.
Attachment #200043 - Attachment is obsolete: true
Attachment #200043 - Flags: review?(darin)
I agree with Nelson's comment. The HTTP code should make the decision, that not receiving a HTTP header response is a failure, and should produce the error, and thereby suppress the UI update. That is the strategy that was behind patch v1. Darin, as you do not like that patch, could you come up with a better way to handle this error on the HTTP protocol level? Or do you have advice that could help us produce the fix to the HTTP code? Thanks.
Assignee: dveditz → darin
Remember that we support HTTP/0.9 responses, which consist of "the document" followed by a closed connection. Is an empty document a valid HTTP/0.9 response? Our code currently assumes that it is. Is it? It seems like it should be valid to me. Since I'm very busy with other FF 1.5 blockers, can someone who can reproduce this bug please take the time to generate a NSPR log for me? NSPR_LOG_MODULES=nsSocketTransport:5,nsHttp:5 That would be very helpful as I could see what is happening inside Necko. Thanks!
Darin, this is a full log of starting Mozilla, loading the mozilla.org homepage, then accessing https://www.mattcooley.com You can search for 9bf3280 for some trace lines from SSL/PSM, that surround the interesting parts of the file.
Attached file nsSocketTransport/nsHttp log (deleted) —
We've been talking about how to keep the secure connection information from showing, but the other way to fix this is to clear the old content display instead. The latter is arguably closer to the reality of the situation.
Yes, I think the bug here is that nsHttpTransaction::ProcessData is never called. That causes us to end up in a partial state, which confuses things downstream. We should treat this response for what it is: an empty document.
I will develop a fix for this.
Status: NEW → ASSIGNED
Target Milestone: mozilla1.8beta5 → mozilla1.8rc1
Attached patch v1 patch (deleted) — Splinter Review
This simple patch fixes the bug. The fix is to treat an empty response as a HTTP/0.9 response. Here, I am just extending the check that is already done to handle unterminated header sections. Instead of calling ParseLineSegment, I use ParseHead, which preserves the old codepath in the case where mLineBuf is not empty. I think this is a fairly safe fix to this bug.
Attachment #200274 - Flags: superreview?(dveditz)
Attachment #200274 - Flags: review?(bzbarsky)
Comment on attachment 200274 [details] [diff] [review] v1 patch r=bzbarsky
Attachment #200274 - Flags: review?(bzbarsky) → review+
Comment on attachment 200274 [details] [diff] [review] v1 patch sr=dveditz
Attachment #200274 - Flags: superreview?(dveditz) → superreview+
Attachment #200274 - Flags: approval1.8rc1?
fixed-on-trunk
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Verified with Linux and Windows trunk builds from 1021
Status: RESOLVED → VERIFIED
to second Tracy, today's winxp branch: http://www.0x90.org/~txs/firefox, ok the cert warnings, the url bar does not change and the lock icon appears. today's winxp trunk: the url switches to https://www.mattcooley.com/ verified on winxp/trunk.
Attachment #200274 - Flags: approval1.8rc1? → approval1.8rc1+
fixed1.8
Keywords: fixed1.8
*** Bug 301757 has been marked as a duplicate of this bug. ***
Group: security
Depends on: 423506
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: