Converting Caddyfile from v1 to v2 xframe issue

1. Caddy version (caddy version): 2.3

2. How I run Caddy: docker

a. System environment: Debian 10.8, Docker 20.10.3

b. Command:

paste command here

c. Service/unit/compose file:

paste full file contents here

d. My complete Caddyfile or JSON config:

{
        email xx@xx.com
}

(common) {
        tls {
                dns lego_deprecated namecheap
                on_demand
        }
        header {
                Strict-Transport-Security "max-age=31536000; includeSubdomains"
                X-XSS-Protection "1; mode=block"
                X-Content-Type-Options "nosniff"
                X-Frame-Options "SAMEORIGIN"
                Referrer-Policy "same-origin"
                -Server
        }
}

domain.com {
        import common
        reverse_proxy localhost:8123 {
		}
}

sub@domain {
        import common
        reverse_proxy localhost:8000 {
                header_down -X-Frame-Options
        }
}

3. The problem I’m having:

Old Caddy 1 I used this:

    proxy / localhost:8123 {
        websocket
        transparent
        header_upstream Authorization {>Authorization}

Now I understand Caddy2 defaults to websocket and transparent anyway but is there an alternative to the Authorization {>Authorization}? I did also sub header_up instead of the old header_upstream

Second, with the sub domain, it won’t let me use the iframe. I get a console error in the browser saying Refused to display ‘https://sub.domain/login’ in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’.

4. Error messages and/or full log output:

as per console log

5. What I already tried:

tried header_down -X-Frame-Options
Also I think a security checker recommended setting the header_up option for authorisation but not sure it’s required now…

6. Links to relevant resources:

Caddy’s default behaviour will already do that. Headers are passed through transparently. Are you certain your backend isn’t getting the header?

Well you’re literally telling Caddy to set that header value via your common snippet. Not sure what you expected :thinking:

I realise transparent is default with caddy2. Are you saying the authorization in header_up is not needed as well? How can I see if the backend is getting the header? Is there a way to view this in chrome?

Yes I am telling Caddy to set SAMEORIGIN in X-Frame-Options. In Caddy1 this allows the sub.domain.com to be viewed in an iFrame. is sub.domain.com not considered to be same origin as domain.com? Is there a way in Caddy2 to allow sub.domain.com to display but not allow iFrames from anywhere else? I was expecting the Caddyv2 behaviour to be the same as Caddyv1

Yeah, because that’s the definition of “transparent”. All headers will be passed through as-is.

I don’t know, you’ll need to debug your backend app. But I’m quite confident Caddy is passing it through, if it gets that header in the request.

No, because Chrome can only show you request and response headers, as it sees them. It cannot show you what the backend sees as the request, because it doesn’t know about the backend. Chrome only knows it’s connecting to “an HTTP server”.

Right, but you said:

So… just don’t set that header then?

This behaviour has nothing to do with Caddy. Those headers are browser-specific decisions.

You can read more about the X-Frame-Options header here:

And it recommends using Content-Security-Policy: frame-ancestors as the modern alternative. This may be what you’re looking for to make it work in subdomains:

Ok but for the last 3 years I had no problems using that directive. I switched to Caddy2 a week ago and it doesn’t work. Maybe there was a chrome upgrade?
Removing the directive and the frame now loads.

Ok so I added that and the frame won’t load again.

I used this:

				Content-Security-Policy "frame-ancestors 'self'"

Instead of self what should I try

Even adding the exact sub-domain to frame ancestors didn’t work.
Also tried adding

                header_down -Content-Security-Policy

To the reverse_proxy but it is ignoring it

The <host-source> mode seems like what you’d want, I think.

header Content-Security-Policy "frame-ancestors 'self' *.domain.com;"

Still get a refusal to connect.

Content-Security-Policy "frame-ancestors 'self' *.domain:xxxxx;"

I use a non-standard port.

The browser console shows Content Security Policy of your site blocks some resources because their origin is not included in the content security policy header
and the directive is the exactly correct resource

So this worked…

Content-Security-Policy "frame-ancestors domain:xxxxx *.domain:xxxxx"

Any idea why?

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