diff --git a/docker/devenv/files/nginx-security-headers.conf b/docker/devenv/files/nginx-security-headers.conf new file mode 100644 index 0000000000..d41baf3a22 --- /dev/null +++ b/docker/devenv/files/nginx-security-headers.conf @@ -0,0 +1,4 @@ +add_header X-Content-Type-Options "nosniff" always; +add_header Referrer-Policy "strict-origin-when-cross-origin" always; +add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; +add_header X-Frame-Options SAMEORIGIN always; diff --git a/docker/devenv/files/nginx.conf b/docker/devenv/files/nginx.conf index c7ac88ac5c..e93ca0750c 100644 --- a/docker/devenv/files/nginx.conf +++ b/docker/devenv/files/nginx.conf @@ -75,10 +75,7 @@ http { etag off; proxy_hide_header X-Powered-By; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; root /home/penpot/penpot/frontend/resources/public; @@ -97,6 +94,7 @@ http { proxy_pass $redirect_uri; proxy_ssl_server_name on; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header x-internal-redirect "$redirect_uri"; add_header x-cache-control "$redirect_cache_control"; add_header cache-control "$redirect_cache_control"; @@ -113,6 +111,7 @@ http { location /internal/assets { internal; alias /home/penpot/penpot/backend/assets; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header x-internal-redirect "$upstream_http_x_accel_redirect"; } @@ -191,6 +190,7 @@ http { location /wasm-playground { alias /home/penpot/penpot/frontend/resources/public/wasm-playground/; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header Cache-Control "no-cache, max-age=0"; autoindex on; } @@ -216,10 +216,7 @@ http { proxy_set_header User-Agent "curl/8.5.0"; proxy_set_header Host "raw.githubusercontent.com"; proxy_set_header Accept "*/*"; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header Access-Control-Allow-Origin $http_origin; proxy_buffering off; } @@ -244,10 +241,7 @@ http { proxy_cache penpot; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header Access-Control-Allow-Origin $http_origin; add_header Cache-Control max-age=86400; add_header X-Cache-Status $upstream_cache_status; @@ -270,28 +264,19 @@ http { proxy_cache penpot; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header Access-Control-Allow-Origin $http_origin; add_header Cache-Control max-age=86400; add_header X-Cache-Status $upstream_cache_status; } location ~* \.(jpg|png|svg|ttf|woff|woff2|gif)$ { - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header Cache-Control "public, max-age=604800" always; # 7 days } location ~* \.(js|css|wasm)$ { - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header Cache-Control "no-store" always; } @@ -299,10 +284,7 @@ http { return 301 " /404"; } - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /home/penpot/penpot/docker/devenv/files/nginx-security-headers.conf; add_header Cache-Control "no-store" always; try_files $uri /index.html$is_args$args /index.html =404; } diff --git a/docker/images/Dockerfile.frontend b/docker/images/Dockerfile.frontend index 9f435551ad..1b44b9c3a1 100644 --- a/docker/images/Dockerfile.frontend +++ b/docker/images/Dockerfile.frontend @@ -17,6 +17,7 @@ ARG BUNDLE_PATH="./bundle-frontend/" COPY $BUNDLE_PATH /var/www/app/ COPY ./files/config.js /var/www/app/js/config.js COPY ./files/nginx.conf.template /tmp/nginx.conf.template +COPY ./files/nginx-security-headers.conf /etc/nginx/nginx-security-headers.conf COPY ./files/nginx-resolvers.conf.template /tmp/resolvers.conf.template COPY ./files/nginx-mime.types /etc/nginx/mime.types COPY ./files/nginx-external-locations.conf /etc/nginx/overrides/location.d/external-locations.conf diff --git a/docker/images/files/nginx-security-headers.conf b/docker/images/files/nginx-security-headers.conf new file mode 100644 index 0000000000..d41baf3a22 --- /dev/null +++ b/docker/images/files/nginx-security-headers.conf @@ -0,0 +1,4 @@ +add_header X-Content-Type-Options "nosniff" always; +add_header Referrer-Policy "strict-origin-when-cross-origin" always; +add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; +add_header X-Frame-Options SAMEORIGIN always; diff --git a/docker/images/files/nginx.conf.template b/docker/images/files/nginx.conf.template index 62d2113076..f365cbd512 100644 --- a/docker/images/files/nginx.conf.template +++ b/docker/images/files/nginx.conf.template @@ -81,10 +81,7 @@ http { etag off; proxy_hide_header X-Powered-By; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /etc/nginx/nginx-security-headers.conf; root /var/www/app/; @@ -105,6 +102,7 @@ http { proxy_ssl_server_name on; proxy_pass $redirect_uri; + include /etc/nginx/nginx-security-headers.conf; add_header x-internal-redirect "$redirect_uri"; add_header x-cache-control "$redirect_cache_control"; add_header cache-control "$redirect_cache_control"; @@ -123,6 +121,7 @@ http { location /internal/assets { internal; alias /opt/data/assets; + include /etc/nginx/nginx-security-headers.conf; add_header x-internal-redirect "$upstream_http_x_accel_redirect"; } @@ -182,10 +181,7 @@ http { include /etc/nginx/overrides/location.d/*.conf; location ~* \.(js|css|jpg|png|svg|gif|ttf|woff|woff2|wasm|map)$ { - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /etc/nginx/nginx-security-headers.conf; add_header Cache-Control "public, max-age=604800" always; # 7 days } @@ -193,10 +189,7 @@ http { return 301 " /404"; } - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; - add_header X-Frame-Options SAMEORIGIN always; + include /etc/nginx/nginx-security-headers.conf; add_header Cache-Control "no-store, no-cache, max-age=0" always; try_files $uri /index.html$is_args$args /index.html =404;