Uncaught SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS

Tiny picture Tiny · Feb 20, 2015 · Viewed 32.5k times · Source

I am using GlassFish Server 4.1/Java EE 7. In my web.xml file, I mentioned the following security constraints.

<security-constraint>
    <display-name>UserConstraint</display-name>
    <web-resource-collection>
        <web-resource-name>Provide a Name</web-resource-name>
        <description/>
        <url-pattern>/admin_side/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <description/>
        <role-name>ROLE_ADMIN</role-name>
    </auth-constraint>
    <user-data-constraint>
        <description/>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

And the same for other authorities.

Since transport-guarantee is set to CONFIDENTIAL, web pages that match the specified URL pattern /admin_side/* run over a secure channel (HTTPS).

While using WebSockets as follows (JavaScript),

var ws = new WebSocket("ws://localhost:8181/Context/Push");

it fails to establish an initial handshake. The browser shows the following warning on the browser console.

[blocked] The page at 'https://localhost:8181/Context/admin_side/Category' was loaded over HTTPS, but ran insecure content from 'ws://localhost:8080/Context/Push': this content should also be loaded over HTTPS.

Uncaught SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

When the <user-data-constraint> section from web.xml is removed in its entirely, web pages run on HTTP. After that, changing,

var ws = new WebSocket("ws://localhost:8181/Context/Push");

to

var ws = new WebSocket("ws://localhost:8080/Context/Push");

works fine.

What might be done to make WebSockets work over a secure channel?

Answer

vtortola picture vtortola · Feb 20, 2015

Try with wss://, that indicates you want a secure websocket connection. The browser will prevent you from creating unsecure connections from secure pages, because it understands that since you requested the page with https://, there is a transport security requirement.

If you have your WebSocket server running with yout Web server, it will probably use the same security certificate and you do not need to do anything. If it does not work, please check your WebSocket server documentation about how to add certificates and enabling wss://.