OnlyOffice integration and external exposure

I have Seafile Server installed in a docker environment, works great. The subdomain I use for that is secured with SSL and HSTS.
I have OnlyOffice installed as well, solely for the purpose of editing office files in the Seafile environment. I have setup the link from Seafile to connect to the OnlyOffice server (running in docker). This is working well.

I am using Nginx Proxy Manager to manage the secure forwarding of subdomains. Both the Seafile and OnlyOffice subdomains are configured to point to the correct server at the backend. In Nginx Proxy Manager I have for both subdomains SSL certificates.

Everything is working, until I switch on HSTS on the OnlyOffice subdomain in the Nginx Proxy Manager. Then, whenever I open an office document in Seafile, I will have a message: “To protect your security, [onlyoffice subdomain] will not allow Firefox to display the page if another site has embedded it.”

Any clue why this is the case, and what I can do to fix this? Seems to be that the option ‘X-Frame-Options’ to ‘sameorigin’ may be the reason why Firefox does not allow it.

Another way I guess is that I may have to move to a direct Nginx environment to get more configuration options.

You can run your site through to confirm if it has the X-Frame-Options headers already. Or you can see that if you load the site, hit F12, go to network tab, F5 to refresh the site, click on one of the items here with a “status” of 200, and look at the headers on the right side.

I’m no expert, but I believe this same message can also happen because of the settings in the content-security-policy header.

In nginx, you would add those with lines like:

add_header X-Frame-Options "SAMEORIGIN";
add_header Content-Security-Policy "default-src";

I don’t know anything about npm, but there’s probably a place in there to put in nginx config options to have it build them into the nginx config it generates.

I am indeed trying to secure the onlyoffice subdomain, and using security headers to check the situation. And indeed the solution lies in the correct configuration of the Nginx Proxy Manager (NPM) reverse proxy.

I am running the onlyoffice service on another subdomain. Within Seafile, document preview is done by loading onlyoffice inside a frame within the seafile subdomain, so setting The X-Frame-Options "SAMEORIGIN" will mess that up. And unfortunately NPM is not so evident to get this fixed.

I got it working using NPM, security headers now give A+ and previews are working as expected!

Since there may be more people running Seafile with OnlyOffice both on their own subdomain behind NPM as reverse proxy. Assuming integration between the two works, but you’re not getting the A+ security headers, NPM is the culprit, and this is what I’ve done. I got it working with information from these NPM discussions:

[How to use 'Custom Nginx Configuration' function to modify headers for added security · Issue #582 · NginxProxyManager/nginx-proxy-manager · GitHub]

And especially the last post in the following discussion:
[Workaround - Security Headers @ NGINX Proxy Manager · GitHub]

In NPM for the proxy host for the onlyoffice subdomain, I switched off the ‘toggle’ for HSTS and added the security headers manually by adding a custom location ‘/’ and add the headers directly under advanced configuration, explicitly removing

add_header X-Frame-Options "SAMEORIGIN";

and adding the following line (I’ve changed the source to her below, but obviously you should put the source to be the Seafile subdomain, since that is the calling parent):

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

So for that specific proxy with NPM the custom location looks like this:


The HSTS toggles are no longer needed, since we will add this ourself manually as below (leaving the toggle on will give duplicate entries in the header which may mess up a browser (you get warnings on for this)

And the advanced configuration is as follows (change frame-ancestors to reflect your seafile subdomain!):

add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" always;
add_header Referrer-Policy strict-origin-when-cross-origin; 
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy upgrade-insecure-requests;
add_header Content-Security-Policy "frame-ancestors 'self'";
add_header Permissions-Policy interest-cohort=();
add_header Expect-CT 'enforce; max-age=604800';
more_set_headers 'Server: Proxy';
more_clear_headers 'X-Powered-By';