Environment
OS: Windows Server 2016 (x64)
App: OnlyOffice DocumentServer (Windows installer, bundled Nginx)
Reverse proxy: Nginx (bundled) terminating TLS on :8443, proxying to docservice (HTTP 127.0.0.1:8000)
Other apps:
IIS app on http://localhost:80 → can embed DocumentServer without issues.
ASP.NET Core app (VS / Kestrel) on https://localhost:5001 → embedding fails due to X-Frame-Options: DENY.
Symptoms
Navigating directly to https://localhost:8443/welcome/: no X-Frame-Options header (good).
Navigating to https://localhost:8443/ (root) which redirects to /welcome/: the redirect response shows X-Frame-Options: DENY.
From the https://localhost:5001 app, attempting to iframe any DocumentServer page results in X-Frame-Options: DENY, even though I’ve disabled/hidden XFO in config and set CSP frame-ancestors to allow the :5001 origin.
Goal
Determine exactly where X-Frame-Options: DENY is being added in this Windows OnlyOffice+Nginx bundle and how to ensure it is never sent (including on 3xx/304/etc.), so that the app on https://localhost:5001 can iframe DocumentServer.
Config (sanitized, minimal)
nginx.conf
worker_processes 1;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
sendfile on; keepalive_timeout 65;
include includes/http-common.conf; # upstream/maps/headers
include ds-custom.conf; # servers below
}
ds-custom.conf
HTTP :8080
server {
listen 8080;
listen [::]:8080;
server_name 127.0.0.1 localhost;
server_tokens off;
# Try to eliminate XFO and allow :5001 via CSP
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options "" always;
add_header Content-Security-Policy "frame-ancestors 'self' http://localhost:5001 https://localhost:5001" always;
include includes/ds-common.conf;
include includes/ds-docservice.conf;
include includes/ds-cache.conf;
include includes/ds-mime.types.conf;
include includes/ds-letsencrypt.conf;
}
HTTPS :8443
server {
listen 8443 ssl http2;
listen [::]:8443 ssl http2;
server_name 127.0.0.1 localhost;
ssl_certificate C:/certs/tls.crt;
ssl_certificate_key C:/certs/tls.key;
ssl_protocols TLSv1.2 TLSv1.3;
server_tokens off;
# Same attempts on TLS server
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options "" always;
add_header Content-Security-Policy "frame-ancestors 'self' https://localhost:5001 https://127.0.0.1:5001 http://localhost:5001" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
include includes/ds-common.conf;
include includes/ds-docservice.conf;
include includes/ds-cache.conf;
include includes/ds-mime.types.conf;
include includes/ds-letsencrypt.conf;
# Extra catch-all location just in case
location ~* ^/.* {
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options "" always;
add_header Content-Security-Policy "frame-ancestors 'self' https://localhost:5001" always;
}
}
Note: The IIS site on http://localhost:80 can embed DS fine; the problem appears when embedding from https://localhost:5001 .
Question
In this OnlyOffice DocumentServer (Windows) + bundled Nginx setup, where could X-Frame-Options: DENY still be injected from, even when:
proxy_hide_header X-Frame-Options; is set,
add_header X-Frame-Options "" always; is used,
and CSP frame-ancestors explicitly allows the :5001 origin?
Is there any known include or default in the Windows package that adds XFO specifically on the root redirect (/ → /welcome/) or other non-proxied responses?
What’s the reliable way to ensure no XFO is sent on all responses (including redirects/304/errors) in this environment? (If the answer is "log it," pointers to logging $sent_http_x_frame_options and $upstream_http_x_frame_options or other directives that can expose the source would be appreciated.)