Nextcloud 28.0.2, Onlyoffice, Nginx: Onlyoffice inacessible when X-Frame-Options set to "SAMEORIGIN" always

Document Server version: 8.0.0.99
Connector version: 9.0.0
DMS (platform) version: ?
OS: OMV on Debian. Running in Docker
Browser version: all browsers

Short summary: Nextcloud wants me to set a header in nginx (The "X-Frame-Options" HTTP header is not set to "SAMEORIGIN". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly.) But when I do set X-Frame-OPtions accordingly, it borks Onlyoffice integration.

Here’s my current ssl.conf:

## Version 2023/08/13 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/ssl.conf.sample

### Mozilla Recommendations
# generated 2023-06-25, Mozilla Guideline v5.7, nginx 1.24.0, OpenSSL 3.1.1, intermediate configuration
# https://ssl-config.mozilla.org/#server=nginx&version=1.24.0&config=intermediate&openssl=3.1.1&guideline=5.7

ssl_certificate /config/keys/cert.crt;
ssl_certificate_key /config/keys/cert.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;

# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /config/nginx/dhparams.pem;

# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;

# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /config/keys/cert.crt;

# Optional additional headers
#add_header Cache-Control "no-transform" always;
##add_header Content-Security-Policy "upgrade-insecure-requests; frame-ancestors 'self'" always;
#add_header Content-Security-Policy "default-src 'self'; script-src 'self'; connect-src 'self';  img-src 'self'; style-src 'self';"
#add_header Permissions-Policy "interest-cohort=()" always;
#add_header Referrer-Policy "same-origin" always;
#add_header X-Content-Type-Options "nosniff" always;
#add_header X-Frame-Options "SAMEORIGIN" always;
#add_header X-UA-Compatible "IE=Edge" always;
#add_header X-XSS-Protection "1; mode=block" always;

Here’s the docker-compose for documentserver:

---
version: "2"
services:
    documentserver:
        image: onlyoffice/documentserver
        container_name: documentserver
        environment:
          - JWT_SECRET=*************
          - PUID=1000
          - PGID=100
          - TZ=Europe/Berlin
          - LANG=en_GB.UTF-8
          - LANGUAGE=en_GB:en
          - LC_ALL=en_GB.UTF-8

        restart: always
        ports:
            - 5025:80
        labels:
            - deunhealth.restart.on.unhealthy=true
        volumes:
            - /srv/dev-*************/config1/onlyoffice/logs:/var/log/onlyoffice
            - /srv/dev-*************/config1/onlyoffice/Data:/var/www/onlyoffice/Data
            - /srv/dev-*************/config1/onlyoffice/lib:/var/lib/onlyoffice
            - /srv/dev-*************/config1/onlyoffice/db:/var/lib/postgresql
            - /srv/dev-*************/config1/onlyoffice/redis:/var/lib/redis
            - /srv/dev-*************/config1/onlyoffice/font:/usr/share/fonts/truetype/custom
            - /srv/dev-*************/config1/onlyoffice/rabbitmq:/var/lib/rabbitmq


networks:
  default:
    name: [same network as nextcloud]
    external: true

And here’s the docker-compose for NC:

---
version: "2"
services:
  nextcloud:
    image: linuxserver/nextcloud
    container_name: nextcloud
    environment:
      - PUID=1000
      - PGID=100
      - TZ=Europe/Berlin
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    volumes:
      - /srv/dev-*************/config1/nextcloud/config:/config
      - /srv/dev-*************/config1/nextcloud/data:/data
      - /srv/dev-*************/media:/media
    links:
      - mariadb
      - redis
    depends_on:
      - mariadb
      - redis
    restart: unless-stopped

This thread: Error message when opening/creating a document from update was useful in identifying the issue. (Note: after commenting the X-Frame-Options in or out, you need to delete browser cookies for your server AND restart Swag for the changes to take effect!)

I currently am able to open documents in NC/Onlyoffice, but the reduced security is not an acceptable long-term solution. Constantine notes in that thread: " If you want to keep using the X-Frame-Options header in your environment, you have to make the Document Server available at the same domain name as your Nextcloud." This is where I am stuck: I am using the same domain name (nextcloud.my.server and documentserver.my.server). What am I missing here?

Or are there additional options that can be set? Back in 2019, someone found a workaround here to a very similar problem: Content Security Policy frame-src forbids nextcloud to load onlyoffice · Issue #54 · ONLYOFFICE/onlyoffice-nextcloud · GitHub

Here’s the proxy-confs for NC and documentserver:

## Version 2023/06/24
# make sure that your nextcloud container is named nextcloud
# make sure that your dns has a cname set for nextcloud
# assuming this container is called "swag", edit your nextcloud container's config
# located at /config/www/nextcloud/config/config.php and add the following lines before the ");":
#  'trusted_proxies' => ['swag'],
#  'overwrite.cli.url' => 'https://nextcloud.example.com/',
#  'overwritehost' => 'nextcloud.example.com',
#  'overwriteprotocol' => 'https',
#
# Also don't forget to add your domain name to the trusted domains array. It should look somewhat like this:
#  array (
#    0 => '192.168.0.1:444', # This line may look different on your setup, don't modify it.
#    1 => 'nextcloud.example.com',
#  ),

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name nextcloud.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app nextcloud;
        set $upstream_port 443;
        set $upstream_proto https;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

        # Hide proxy response headers from Nextcloud that conflict with ssl.conf
        # Uncomment the Optional additional headers in SWAG's ssl.conf to pass Nextcloud's security scan
        proxy_max_temp_file_size 2048m;
        
#        proxy_hide_header Referrer-Policy;
#        proxy_hide_header X-Content-Type-Options;
#        proxy_hide_header X-Frame-Options;
#        proxy_hide_header X-XSS-Protection;

        # Disable proxy buffering
        proxy_buffering off;
    }
}
## Version 2023/05/31
# make sure that your onlyoffice documentserver container is named documentserver
# make sure that your dns has a cname set for documentserver

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name documentserver.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;


    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app documentserver;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }
}

hi @user-of-file :wave:

  1. Could you please specify which guides you used for installing NextCloud and ONLYOFFICE?
  2. Are NextCloud and ONLYOFFICE deployed on the same machine?
  3. Is the warning appearing on the NextCloud side?
    If I understand correctly, there are no issues with the functionality of ONLYOFFICE docs itself.
  1. I don’t recall what guide I used to install OnlyOffice. It was around a year ago. My NC has been running for 2+ years now, using this guide: Let's Encrypt, Nginx & Reverse Proxy Starter Guide - 2019 Edition | LinuxServer.io

  2. Nextcloud and OnlyOffice are deployed on the same machine, yes. As Docker containers, with the OnlyOffice container associated with the same network as the Nextcloud container.

  3. No. The "X-Frame-Options" HTTP header is not set to "SAMEORIGIN". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly. appears in Nextcloud. Fixing that issue (by commenting in add_header X-Frame-Options "SAMEORIGIN" always; in ssl.conf in the Swag/Nginx container) leads to the following warning in Firefox when I try to open a .docx file via Nextcloud:

Firefox Can’t Open This Page

To protect your security, documentserver.vibraphone.one will not allow Firefox to display the page if another site has embedded it. To see this page, you need to open it in a new window.

So the warning is appearing on the documentserver/OnlyOffice side.

Here’s my docker-compose for Lets Encrypt/Swag/Nginx:

letsencrypt:
image: linuxserver/swag
container_name: swag
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=100
- TZ=Europe/Berlin
- URL=*******
- SUBDOMAINS=wildcard
- VALIDATION=dns
- DNSPLUGIN=porkbun
- EMAIL=************
volumes:
- /srv/***********/config1/letsencrypt:/config
ports:
- 443:443
- 80:80
restart: unless-stopped

Applications Nextcloud and ONLYOFFICE should be accessible under the same domain, rather than different subdomains.
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

Try using paths like my.server/nextcloud and my.server/documentserver instead of nextcloud.my.server and documentserver.my.server.

This might help resolve the issue you’re stuck on.

But these are restrictions imposed by a third party.
Adding the X-Frame-Options header affects access to the document server, as it prohibits displaying the page in a frame (Different origins).

The page can only be displayed if all parent frames have the same origin as the page itself.
However, this issue is not on the document server side.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options#sameorigin

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

It would be acceptable for Onlyoffice to be accessible under a path like nextcloud.my.server/documentserver, but changing the URL of my Nextcloud instance is currently not feasible.

I note that the proxy-confs for nginx as supplied by linuxserver’s SWAG reverse proxy currently only contain subdomain options for documentserver.

I also note that Collabora is able to function without issue with the X-Frame-Options header. (No Nextcloud branding is visible however, unlike with OnlyOffice, so I couldn’t speak to whether it is embedded into nextcloud.my.server by different means).

As OnlyOffice offers integration with Nextcloud, it should be functional with Nextcloud’s recommended security settings.