Home > Enterprise >  websocket connection fails after adding Content-Security-Policy in nginx
websocket connection fails after adding Content-Security-Policy in nginx

Time:11-22

I want to add a new header Content-Security-Policy to my nginx conf in order to improve security. I've added all external sources and everything works fine except for the chatbot which is infobip. It uses wss protocol and for some reason I can't find the right way to configure it.

This is the error that I get.

And this is my the header in nginx.conf

add_header 'Content-Security-Policy' "default-src 'self' 'unsafe-inline' wss: wss://.infobip.com ws://.infobip.com .infobip.com http://www.w3.org https://fonts.googleapis.com https://stackpath.bootstrapcdn.com .youtube.com https://cdn.jsdelivr.net/; img-src 'self' data: https://.openstreetmap.org wss://livechat-fr.infobip.com/chat/web/proxy/827/toxgylwd/websocket always; connect-src 'self' wss: ws: wss://.infobip.com ws://*.infobip.com .infobip.com https://.doubleclick.net wss://livechat-fr.infobip.com/chat/web/proxy/492/hybzmnjl/websocket 'unsafe-inline' always;";

I've tried numerous ways to allow the websocket connection but none seems to work.

CodePudding user response:

Since every websocket connection start by a regular http request, you must add a CSP for https://your-websocket-server-domain:port

The http request will be answered with a 101: swtiching protocols and then the connection will become a WebSocket connection.

Note that I don't think that the ws: or wss: csp directive is required at all.

CodePudding user response:

You have 2 issues:

  1. Wrong format of Nginx add_header. It should looks like (pay attention to quotes - always keyword should be placed out of the CSP settings):

    add_header Content-Security-Policy "default-src 'self'..." always;

  2. Wrong format of CSP's host-sources. Host-sources like .youtube.com must not contain a leading . dot:
    youtube.com will allow to load resources from http(s)://youtube.com and *.youtube.com will allow resources from the subdomains of youtube.com.

So your syntactically correct CSP should looks like:

add_header Content-Security-Policy "\
default-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com\
https://fonts.googleapis.com infobip.com ws://infobip.com wss://infobip.com youtube.com\
https://cdn.jsdelivr.net http://www.w3.org;\
connect-src 'self' infobip.com wss://infobip.com ws://*.infobip.com\
wss://livechat-fr.infobip.com/chat/web/proxy/492/hybzmnjl/websocket https://doubleclick.net;\
img-src 'self' data: https://openstreetmap.org;\
" always;

Note that:

  • The scheme-sources like wss: covers any host-sources with that scheme (eg wss://site.com/websocket). So I deleted the scheme-sources and left the host-sources.
  • I deleted some unsupported sources, for instance 'unsafe-inline' in the connect-src.
  • Nginx should support a backslash \ as line break, so I used it because it's hard to maintain CSP in one line. Check does your Nginx version supports this feature.

Note 2: This CSP can block some sources - just add them to the appropriate directives.

Note 3: Consider moving the sources from the default-src directive to the script-src style-src font-src directives. Because for now you actually allows 'unsafe-inline' in the scrit-src so your CSP does not protect against XSS. It will also be difficult to manage CSP in the future, since the sources are mixed in one directive.

  • Related