Do not allow mixed-content WebSockets

RESOLVED FIXED in mozilla8



Networking: WebSockets
6 years ago
4 years ago


(Reporter: briansmith, Assigned: mcmanus)



Bug Flags:
in-testsuite ?

Firefox Tracking Flags

(Not tracked)


(Whiteboard: [inbound])


(2 attachments)

When a script attempts to open a WebSocket to a non-TLS-protected server ("ws://"), the attempt should fail if the document was delivered over HTTPS.

Since there are basically no existing WebSockets servers, there is no compatibility reason to allow ws:// (as opposed to wss//) WebSockets from an https:// webpage. We would like to move to a stronger policy prohibiting all mixed content, and prohibiting https://+ws:// from the start will help prevent WebSockets from adding to the problem.

In addition to addressing this in code, we should make sure the W3C spec notes this.

Comment 1

6 years ago
Created attachment 544854 [details] [diff] [review]
patch v1
Attachment #544854 - Flags: review?(cbiesinger)

Comment 2

6 years ago
Comment on attachment 544854 [details] [diff] [review]
patch v1

whoops - this is a content code change.. changing reviewer.
Attachment #544854 - Flags: review?(cbiesinger) → review?(Olli.Pettay)

Comment 3

6 years ago
Comment on attachment 544854 [details] [diff] [review]
patch v1

This is not per spec, but I think we should do this.

Please bring this up in Web Apps WG.
Attachment #544854 - Flags: review?(Olli.Pettay) → review+

Comment 4

6 years ago
pushed to inbound

Jonas or Brian - can you bring this to the web apps wg?
Whiteboard: [inbound]
Pushed to m-c:
Last Resolved: 6 years ago
Flags: in-testsuite?
Resolution: --- → FIXED
Whiteboard: [inbound]
Target Milestone: --- → mozilla8
Attachment #544854 - Flags: review+

Comment 6

6 years ago
Wouldn't the right check be a check for security info from the callsite, not the url scheme?  Hardcoding https and assuming that we don't support any other secure schemes seems bad.
Keywords: dev-doc-needed

Comment 7

6 years ago
Created attachment 546637 [details] [diff] [review]

Do you think this is better?
Attachment #546637 - Flags: review?(bzbarsky)

Comment 8

6 years ago
Comment on attachment 546637 [details] [diff] [review]

This seems good; just document that since this is in Init() the document associated with this script context is still the same one as associated with mOwner?

Or should we add an assert to that effect?

Oh, and fix the indent on that return statement, please.
Attachment #546637 - Flags: review?(bzbarsky) → review+


6 years ago
Resolution: FIXED → ---


6 years ago
Whiteboard: [inbound]
Last Resolved: 6 years ago6 years ago
Resolution: --- → FIXED
Documentation updated:

Also referenced on Firefox 8 for developers.
Keywords: dev-doc-needed → dev-doc-complete

Comment 11

4 years ago
Would it be possible to have a clearer statement of the rationale for this, please. This is a major change that prevents a number of very reasonable use-cases from happening.

Suppose I want to make a webapp that implements an SSH client (for connecting to machines that have a WebSocket-enabled SSH server, or via a proxy). The webapp has to be served over HTTPS: if it's not, a man in the middle could inject some javascript and sniff your password, everything. You have to make the webapp HTTPS.

This change implies that a secure webpage isn't allowed to make decisions about what resources it connects out to. It's absolutely right that an HTTPS page shouldn't load non-HTTPS code (JS files), and it's a nasty leak if it loads non-secure documents or files (image resources). But, a WebSocket connection isn't a file or document, it's a communication channel. It's not up to the browser to patrol what goes over that channel. Instead the browser just passes up any data it receives to the JS handlers, which do the input validation.

This is a normal security model: code you trust connects out to something it doesn't trust, and carefully communicates with it, doing the appropriate validation of input.

The only alternative, according to this bug, is to give every SSH server I want to connect to a certificate that's trusted by the browser. These machines don't have a global hostname on a domain that a CA will sign for. That's just not reasonable if I want my SSH client to connect to machines on my local network. It never used to be necessary to globally register an SSH server in order to connect to it. Just a postit with the fingerprint is enough, or some other out-of-band way of getting the signatures (via my webservice over HTTPS).

The model is that there's a webservice that can relay connections for NAT traversal, but it should be possible to make a direct connection when the client and server are on the same network together. It's not possible for me to issue certificates or require all these WebSocket servers to have certificates. They should be able to just connect, and the secure JavaScript hosted in the browser can handle things itself.

Now that Firefox has asm.js that works with OpenSSL, there's no reason it can't do pretty fast AES and DH for an SSH connection, for example. Requiring WebSocket servers to use TLS is a huge blow.

I seriously suggest this is reconsidered, or it's not going to be possible for anyone to provide these sorts of services. Basically anything that involves WebSocket connections to listening services that aren't public on the internet is messed up by this.
(In reply to Nicholas Wilson from comment #11)
> Would it be possible to have a clearer statement of the rationale for this,
> please.

We don't have any evidence that users understand the lock icon to mean "no non-secure code was loaded but there may be unprotected communication happening behind the scenes." There's no distinction between the case of "no secure communication" and "no secure code loading" in the UI, and adding such a distinction is difficult to justify.

> This is a major change

This change happened over two years ago. Also, this is the behavior that the specification requires (though, I was one of the people that pushed for that requirement to be added to the spec).

> that prevents a number of very reasonable use-cases from happening.

I agree. However, it also makes the UI clear in some important use cases.

For example, consider an HTML5 email client (that uses mozTCPSocket or some websockets proxy) that has been mis-configured to use the non-TLS-protected communication channel. As IMAP/SMTP/POP/LDAP almost always send your password otherwise unprotected on the wire, it is really important to use TLS.

In general, going forward we may need to allow some kinds of mixed content (websockets and/or XHR or whatever), but I suspect in the vast majority of cases the server could "just" switch to HTTPS.

Your SSH example is quite unusual case because it is another well-established secure protocol. IMO, the SSH example is better off using mozTCPSocket (at least, once it is in the browser and once it becomes standardized). And, one of the issues with mozTCPSocket is that we probably have to ask for permission. It is possible that, as part of that permission prompt, that we could allow "mixed" mozTCPSocket connections. Or, maybe not; it hasn't been decided either way. Even still, the SSH example suffers (AFAICT) from the inability to use public key authentication instead of password authentication. See
Also, my mistake: instead of having this discussion in this closed-for-two-years bug, let's please move it to dev-security or dev-tech-networking. Please CC me if you do so.

Comment 14

4 years ago
Brian, thanks very much for replying. It was a bit of an outburst! My surprise is entirely my fault; we should have tested serving the webapp over TLS to firefox when we weren't so far down the line with the product (we did our main testing on Chrome, unfortunately). I'll continue this on the mailing list.
You need to log in before you can comment on or make changes to this bug.