skip to Main Content

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. You have 3 issues:

    1. Console errors you shown are not CSP-related. "403 Forbidden" means you do not have access to related Url. "’X-Frame-Options’ to ‘deny’" means you try to embed iframe but that page disallows embedding via X-Frame-Options: "DENY" HTTP header.

    2. 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;

    3. 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/ https://doubleclick.net;
    img-src 'self' data: https://openstreetmap.org;
    " always;

    Note that:

    • wss://livechat-fr.infobip.com/chat/web/proxy/492/hybzmnjl/websocket – do not include bold path-part to CSP, because it’s changed each time.
    • 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search