Iframe embedding problem with calendar 2.x

OC Version: 10.11.0 (stable), calendar plugin 2.0.0

I want to embed a shared calendar from https://cloud.netzwissen.de to another page running in a CMS on https://netzwissen.de by using <iframe>...</iframe>. But the X-Frame-Options = SAMEORIGIN header blocks the embedding although both servers run on the same domain (but in different containers with different host URLs).

Do we have a direct setting in OC which allows to specifically embed the calendar links or allow the embeddigng within the same subdomain? As far as I understand SAMEORIGIN means “same URL” and this is the reason that kills my setup here ;-( …

Thanks for some ideas,
Thommie

Hi thommie,

I think you will have to set your own Content Security Policy permitting the domain netzwissen.de.

When I read the gist MyCSP app for ownCloud · GitHub correctly (coming from How to correctly set CSP?) you would have to create an app, where you use addAllowedFrameDomain instead of addAllowedScriptDomainin the example.

All available methods are found at core/EmptyContentSecurityPolicy.php at master · owncloud/core · GitHub

I have not tried it myself, so let us know, if it is working :wink:

Hmmm, ok, but that really sounds like “cracking a nut with a sledgehammer” …

The calendar app offers a public link to share a calendar “read only” as html/javascript with an url such as:

[oc-server]/index.php/apps/calendar/embed/[xxxxxx]

(this is NOT the caldav link used elsewhere). I also looked into config.php and there I have both domains set in

cors.allowed-domain
trusted_domains

Thus it should be possible to embed this code into other sites within the same domain. At least with some special fine-tuning of the headers/config …

CORS does not apply for embedding the ownCloud on another site. AFAIK, the only way around it, is to extend the default CSP. This can be done in the reverse proxy in front of your ownCloud or in the web server that serves ownCloud (would not recommend this way if oC is running in a container).

A CSP extension can look like this, but depending on the used webserver/proxy the syntax might be different:

Header merge Content-Security-Policy "frame-ancestors 'self' https://netzwissen.de"

Remember this is a security feature, and you should be as strict as possible.

You can check the header by a simple curl request:

❯ curl -I http://10.168.64.122:8000/index.php/apps/calendar/embed/ZKAE9WBUSTHKH4GA
HTTP/1.1 200 OK
Date: Wed, 05 Oct 2022 13:42:37 GMT
Server: Apache
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
X-Robots-Tag: none
X-Frame-Options: SAMEORIGIN
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Set-Cookie: ocwm1duxquzd=r7loihns4tb284178agq47keqk; path=/; HttpOnly; SameSite=Strict
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Set-Cookie: oc_sessionPassphrase=Dbqd9xWo8nNcf%2Bfw4gnaCchRvjViBTBIrhNYX8TeLSQatuJ05IHnOFIXlFW3pszT5vL4RTK%2B5qFaG%2Ba7ftK5e4J01d2PPTGviLoTbYnaP6TJ4bzWrNSCxXiMTU4ZdIz9; expires=Wed, 05-Oct-2022 14:02:37 GMT; Max-Age=1200; path=/; HttpOnly; SameSite=Strict
Content-Security-Policy: default-src 'none';manifest-src 'self';script-src 'self' * 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self', frame-ancestors 'self' file:
Content-Length: 35449
Content-Type: text/html; charset=UTF-8

In this example, I have extended the CPS by a frame-ancestors 'self' file: to allow embedding on a local file by frame-ancestors 'self' file:. It’s important to keep the original parts of the CSP, as these are set dynamically. A hard override of the dynamic CSP header with a static one may cause other issues.

Thanks @rkaussow , I think, thats the correct direction ;-)).

The OC operates in a container, but LXC, not docker (virtualized with proxmox VE) and there is a haproxy in front for ssl termination. So I believe this could be managed either with some settings in the haproxy backend config or on the local apache inside the container. I would also prefer the haproxy way …

Not sure if haproxy has a proper replacement for Apaches Header merge directive, if not I would go the Apache way as overwriting the entire CSP with a static one is nearly impossible due to the already mentioned dynamic handling in core and all apps.

Small note on this approach. I noticed that Apache Header merge will merge headers with a , instead of a ; which is invalid for CSP. To workaround this issue yet another “hack” is required:

Header merge Content-Security-Policy "frame-ancestors 'self' https://netzwissen.de"
Header edit* Content-Security-Policy , ;

This will create a valid CSP.

1 Like

This is interesting, maybe this could make it’s way to the documentaition.

Out of curiosity, do you think @butonic’s gist at MyCSP app for ownCloud · GitHub is (still) working? That could be a solution for users who do have admin access to their cloud but not to the web server configuration.

Not sure, this approach is pretty old already and IMO a custom app just to extend the CSP is really a bit overkill. If users don’t have access to the web servers config, this can be done via .htaccess as well. Users might need to deal with the integrity check and need to add it back after each upgrade, but still better than a custom app.

However, if you would like to try the custom app approach, I would be interested in the results :slight_smile:

1 Like

@rkaussow - thanks a lot, your approach worked perfectly!

I first played with haproxy (latest stable 2.6). But as far as I understand, it only allows to set fixed additional headers. You can add headers e.g. for Strict-Transport-Security or the X-Forwarded-xxx headers for the proxy itself, thats easy.

But I could not find any docs about merging of header value strings coming from an application with additional values from haproxy. Therefore I implemented it with your recommendation (the apache way) and it worked directly :wink:

Will still ask the haproxy devs if there is a way to do this in the haproxy, it may be useful as an alternative and for documentation …

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.