Content Security Policy connect-src with wss domain

1. Caddy version (caddy version):

v2.4.6

2. How I run Caddy:

standard install on debian 10 with official repo run by systemd

a. System environment:

debian 10

3. The problem I’m having:

I am setting up specific CSP header for the reverse proxy of an app.
I have only one issue when declaring a wss:// domain for connect-src

it seems like it is transformed by caddy into https:// instead of wss

4. Error messages and/or full log output:

I have an error when requesting via curl on via my app

5. What I already tried:

I have already set up many other different specific CSP with no issues but only this one on wss does not work
I have restarted / stopped and rebooted to see but no help

6. Links to relevant resources:

Please be more specific. What’s in your config? What are you seeing in your logs?

1 Like

in my config is some header I setup for my reverse proxy like below

(logging) {
        log {
                output file /var/log/caddy/access.log
        }
}

(header) {
        header {
                Strict-Transport-Security "max-age=31536000; includeSubDomains; always"
                X-XSS-Protection "1; mode=block;"
                X-Robots-Tag "none;"
                X-Frame-Options "SAMEORIGIN"
                X-Permitted-Cross-Domain-Policies "none"
                X-Download-Options "noopen"
                Acces-Control-Allow-Origin "*;"
                Referrer-Policy "strict-origin-when-cross-origin"
                Server "No."
        }
}

toto.super.com {
        import logging
        import header

        reverse_proxy 127.0.0.1:3000 {
                header_down cross-origin-embedder-policy "require-corp"
        }
        reverse_proxy /api/broadcast 127.0.0.1:3000 {
                header_down cross-origin-resource-policy "cross-origin"
                header_down cross-origin-embedder-policy "require-corp"
        }
        reverse_proxy /api/config 127.0.0.1:3000 {
                header_down cross-origin-resource-policy "cross-origin"
                header_down cross-origin-embedder-policy "require-corp"
        }

        header / Content-Security-Policy "default-src 'none'; child-src https://toto.super.com; worker-src 'self'; media-src blob:; style-src 'unsafe-inline' 'self' https://toto.super.com; script-src 'self' resource: https://toto.super.com; connect-src 'self' blob: https://toto.super.com https://toto-tata.super.com wss://toto.super.com; font-src 'self' data: https://toto.super.com;img-src 'self' data: blob: https://toto.super.com; frame-src 'self' blob: https://toto-tata.super.com"
        header /sheet/inner.html Content-Security-Policy "default-src 'none'; child-src https://toto.super.com; worker-src 'self'; media-src blob:; style-src 'unsafe-inline' 'self' https://toto.super.com; script-src 'self' 'unsafe-eval' 'unsafe-linline' resource: https://toto.super.com; connect-src 'self' blob: https://toto.super.com https://toto-tata.super.com wss://toto.super.com; font-src 'self' data: https://toto.super.com;img-src 'self' data: blob: https://toto.super.com; frame-src 'self' blob: https://toto-tata.super.com"

        redir / /drive
}

when the application I am hosting is passing a self-checkup test the result come differently for the content-security-policy header for the field of connect-src where the value ‘wss://toto.super.com’ appear as ‘https://toto.super.com

we did some test with the dev team of the application to confirm the issue.
the only difference is in caddy configuration, with nginx it works normally.
I only need to setup correctly those headers.

https://toto.super.com/ was served with incorrect Content-Security-Policy headers.

A value of "'self' blob: https://toto.super.com https://tata-toto.super.com wss://toto.super.com" was expected for the connect-src directive.
Failed test number	26
Returned value	

{
 "default-src": "'none'",
 "style-src": "'unsafe-inline' 'self' https://toto.super.com",
 "font-src": "'self' data: https://toto.super.com",
 "child-src": "https://toto.super.com",
 "frame-src": "'self' blob: https://tata-toto.super.com",
 "connect-src": "'self' blob: https://toto.super.com https://toto.super.com https://toto-tata.super.com",
 "img-src": "'self' data: blob: https://toto.super.com",
 "media-src": "blob:",
 "frame-ancestors": "*",
 "worker-src": "'self'",
 "script-src": "'self' resource: https://toto.super.com"
}

Also I have noticed that if I add for example the header cache-control “no-cache” or x-content-type-options “nosniff” they became redundant from the application perspective when they are not set in my configuration…

I am wondering how caddy is handling header and if there some under-the-hood happening here.

Remove the ; at the end of each of those header lines. The syntax for these headers don’t take a semicolon:

You have a / matcher here, which means only requests to exactly / will return that header. Remove the / to make sure it applies to all request paths.

I can’t say what you’d need to fix in your Content-Security-Policy header, if something’s wrong with it, I don’t have much experience with that, and it’s out of scope of Caddy, since it’s a browser behaviour.

why is caddy adding some header by default and which of them ?

why do I have a double header of content-security-policy (with this configuration I show you but I took off the / matcher on your advise) when requesting at https://toto.super.com/index.html but not at http://toto.super.com ?

Thanks @francislavoie for your help :pray:

Which headers are you talking about? That’s a vague question.

The only header Caddy adds automatically without conditions is Server: Caddy but that’s harmless.

If your upstream app is setting it and Caddy is also setting it, then it’ll appear twice. If you want to always remove the value the upstream is sending back so only the one you set in Caddy is used, then you can do header_down -Content-Security-Policy inside your reverse_proxy options

This topic was automatically closed after 30 days. New replies are no longer allowed.