If like us you’re using WebSockets, Express, and the helmet library in order to lock down your websites Content-Security-Policy (CSP), you might have noticed that setting the ‘connect-src’ field to “‘self'” doesn’t permit connections on the ws:// protocol, even if the origin of the WebSocket server is the same. In fact, you may have noticed this no matter what your development stack is. Of course, CSP is not unique to the aforementioned technologies.
Something that wasn’t immediately clear to us when using the “‘self'” policy is that it not only refers to the origin but also the protocol and port. So, this means that “‘self'” does not match the ws:// scheme. In order to satisfy the browser and reassure it that connections to your WebSocket server are safe you will unfortunately have to explicitly set the WebSocket’s server address as a property on the connect-src field. For example, using the helmet.js Express library:
var hostname = 'domain.com'; app.use(helmet.contentSecurityPolicy({ connectSrc: [ "'self'", "ws://" + hostname ] }));
In the example above hostname is set to the example ‘domain.com’ however it is likely that you will actually be pulling this value from a configuration file so that the policy reflects the execution environment, such as localhost, or a staging or production server. Also, if your WebSocket server is not running over the default port 80, then you will also have to include this in the declaration.
Happy CSPing!
– Sam