Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: nginx sec headers #4397

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ ENV SCRUMLR_ANALYTICS_DATA_DOMAIN=''
ENV SCRUMLR_ANALYTICS_SRC=''

COPY ./nginx.conf /etc/nginx/templates/scrumlr.io.conf.template
COPY ./security-headers.conf /etc/nginx/conf.d/security-headers.conf
COPY --from=build-stage /usr/src/app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
4 changes: 2 additions & 2 deletions deployment/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
scrumlr-backend:
restart: always
build:
context: ../server/src/
context: ../../server/src/
dockerfile: Dockerfile
command:
- "/app/main"
Expand Down Expand Up @@ -42,7 +42,7 @@ services:
scrumlr-frontend:
restart: always
build:
context: ../.
context: ../../.
dockerfile: Dockerfile
environment:
SCRUMLR_SERVER_URL: "${SCRUMLR_SERVER_URL}"
Expand Down
45 changes: 26 additions & 19 deletions nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,66 @@ server {
server_name beta.scrumlr.io scrumler.io scrumlr.de;

location / {
return 301 https://scrumlr.io$request_uri;
return 301 https://scrumlr.io$request_uri;
}
}

server {
listen ${SCRUMLR_LISTEN_PORT} default_server;
listen [::]:${SCRUMLR_LISTEN_PORT} default_server;
server_name _;
server_name _;

root /usr/share/nginx/html;
index index.html index.htm;

gzip on;
gzip_vary on;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 1024;
gzip_disable "MSIE [1-6]\.";

include /etc/nginx/conf.d/security-headers.conf;

location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-store, no-cache, must-revalidate";
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-store, no-cache, must-revalidate";
include /etc/nginx/conf.d/security-headers.conf;
}

location /index.html {
# Application specific feature toggles
add_header Set-Cookie "scrumlr__show-legal-documents=${SCRUMLR_SHOW_LEGAL_DOCUMENTS};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__server-url=${SCRUMLR_SERVER_URL};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__websocket-url=${SCRUMLR_WEBSOCKET_URL};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__analytics_data_domain=${SCRUMLR_ANALYTICS_DATA_DOMAIN};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__analytics_src=${SCRUMLR_ANALYTICS_SRC};Path=/;Max-Age=3600";

# Disable caching for index.html
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma no-cache;
expires 0;
# Application specific feature toggles
add_header Set-Cookie "scrumlr__show-legal-documents=${SCRUMLR_SHOW_LEGAL_DOCUMENTS};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__server-url=${SCRUMLR_SERVER_URL};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__websocket-url=${SCRUMLR_WEBSOCKET_URL};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__analytics_data_domain=${SCRUMLR_ANALYTICS_DATA_DOMAIN};Path=/;Max-Age=3600";
add_header Set-Cookie "scrumlr__analytics_src=${SCRUMLR_ANALYTICS_SRC};Path=/;Max-Age=3600";

# Disable caching for index.html
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma no-cache;
expires 0;
include /etc/nginx/conf.d/security-headers.conf;
}

location ~* \.(js|json)$ {
# Cache JS and JSON files for 3 days
expires 3d;
add_header Cache-Control "public, must-revalidate";
include /etc/nginx/conf.d/security-headers.conf;
}

location ~* \.(jpg|jpeg|gif|png|svg|css)$ {
# Cache other media files for 14 days
expires 14d;
add_header Cache-Control "public";
add_header Cache-Control "public, must-revalidate";
include /etc/nginx/conf.d/security-headers.conf;
}

location ~* \.(ico|mp3)$ {
# Cache .mp3 and .ico files for 365 days
add_header Cache-Control "max-age=36792000, public";
# Cache .mp3 and .ico files for 365 days
add_header Cache-Control "max-age=36792000, public";
include /etc/nginx/conf.d/security-headers.conf;
}
}
8 changes: 8 additions & 0 deletions security-headers.conf
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm usually a proponent of splitting stuff into multiple files, however I'm not sure in this case because it adds another file to the project root. Could you add in into the main file or if you want to split it maybe add a subdirectory?

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Security headers
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always;
add_header Permissions-Policy "interest-cohort=()" always;
add_header X-Frame-Options "DENY" always;
add_header Expect-CT "max-age=86400, enforce" always;
Loading