Skip to content
This repository has been archived by the owner on Mar 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request from GHSA-gwq3-pvwq-4c9w
Browse files Browse the repository at this point in the history
Added security headers to UI requests
  • Loading branch information
bartvanb committed Mar 7, 2024
2 parents 1e25614 + 25950fe commit 68dfa66
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 6 deletions.
9 changes: 4 additions & 5 deletions Dockerfile
Expand Up @@ -10,12 +10,11 @@ RUN npm run build

# run
FROM nginx:alpine
COPY --from=node /app/startup /app/startup
COPY --from=node /app/dist/vantage6-UI /usr/share/nginx/html


# add option to not share server info to nginx config file. Be sure to do this
# in the http block, which is achieved by matching that line
RUN sed -i '/http {/a \ \ \ \ server_tokens off;' /etc/nginx/nginx.conf
# Copy nginx config file to container
COPY nginx.conf /etc/nginx/nginx.conf

# When the container starts, replace the env.js with values from environment variables and then startup app
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/assets/env.template.js > /usr/share/nginx/html/assets/env.js && exec nginx -g 'daemon off;'"]
CMD ["/bin/sh", "-c", "/app/startup/replace_env_vars.sh && exec nginx -g 'daemon off;'"]
18 changes: 18 additions & 0 deletions README.md
Expand Up @@ -71,3 +71,21 @@ If you don't enter environment variables, the UI points to
Note that you can also use another UI image tag than `ui:latest`. For example,
you can specify a version of the UI such as `ui:3.6.0`. Another option is
to use the tag `ui:cotopaxi`, which defaults to the latest v4 version.

#### Security settings

Finally, there is also an environment variable `ALLOWED_ALGORITHM_STORES` that
you can specify. If you do so, the appropriate
[CSP headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) will be
set so that your UI can only access the vantage6 server and algorithm stores
to collect data from. You define them same as other environment variables, with
spaces in between each algorithm store you want to allow traffic from:

```
docker run --env ALLOWED_ALGORITHM_STORES="store.cotopaxi.vantage6.ai myotherstore.com" ...
```

Note that if you do *not* specify this environment variable, the CSP policy
will be very lenient. In order for the UI to work properly, algorithm store
resources should be obtained, so if no algorithm stores are provided, all
URIs will be allowed.
10 changes: 9 additions & 1 deletion angular.json
Expand Up @@ -41,7 +41,15 @@
"maximumError": "4kb"
}
],
"outputHashing": "all"
"outputHashing": "all",
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
}
},
"development": {
"buildOptimizer": false,
Expand Down
46 changes: 46 additions & 0 deletions nginx.conf
@@ -0,0 +1,46 @@
user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


http {
# hide nginx version
server_tokens off;

#### Add security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Cache-Control "no-cache, no-store";

# Add CSP policy. Allow the following URLs for the following reasons:
# - fonts.gstatic.com and fonts.googleapis.com: Google Fonts and Material Icons
# - localhost:* and ws://localhost:*: Webpack Dev Server
# - self: own content
# Note that in angular.json, the production 'optimization' configuration was
# updated to the value provided in https://stackoverflow.com/a/71302985/5398197
# to prevent the need to add 'unsafe-inline' to the default-src directive.
add_header Content-Security-Policy "default-src 'self'; connect-src 'self' <SERVER_URL> <ALGORITHM_STORE_URLS> ws://<SERVER_URL_NO_HTTP> wss://<SERVER_URL_NO_HTTP>; font-src https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com";

include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;

keepalive_timeout 65;

include /etc/nginx/conf.d/*.conf;
}
1 change: 1 addition & 0 deletions src/assets/env.js
Expand Up @@ -6,4 +6,5 @@
window["env"]["server_url"] = "https://cotopaxi.vantage6.ai";
window["env"]["api_path"] = "";
window["env"]["api_url"] = "https://cotopaxi.vantage6.ai";
window["env"]["allowed_algorithm_stores"] = "*";
})(this);
1 change: 1 addition & 0 deletions src/assets/env.template.js
Expand Up @@ -6,4 +6,5 @@
window["env"]["api_url"] = "${API_URL}";
window["env"]["server_url"] = "${SERVER_URL}";
window["env"]["api_path"] = "${API_PATH}";
window["env"]["allowed_algorithm_stores"] = "${ALLOWED_ALGORITHM_STORES}";
})(this);
26 changes: 26 additions & 0 deletions startup/replace_env_vars.sh
@@ -0,0 +1,26 @@
#!/bin/sh

# replace environment variables for angular app
envsubst < /usr/share/nginx/html/assets/env.template.js > /usr/share/nginx/html/assets/env.js

# replace environment variables for nginx config. There the URL (without http(s))
# is used in the Content-Security-Policy header.
# TODO the following process to set nginx configuration via sed is not ideal. Consider
# doing it by directly using env vars in nginx.conf (see https://github.com/docker-library/docs/tree/master/nginx#using-environment-variables-in-nginx-configuration-new-in-119)
if [ -z "${SERVER_URL}" ]; then
SERVER_URL="https://cotopaxi.vantage6.ai"
fi
# Remove http(s) from the server url
SERVER_URL_NO_HTTP=$(echo "$SERVER_URL" | sed 's/^https\?:\/\///g')
# escape the slashes in the url
SERVER_URL=$(echo "$SERVER_URL" | sed 's/\//\\\//g')
sed -i "s/<SERVER_URL>/$SERVER_URL/g" /etc/nginx/nginx.conf
sed -i "s/<SERVER_URL_NO_HTTP>/$SERVER_URL_NO_HTTP/g" /etc/nginx/nginx.conf

# also whitelist the allowed algorithm stores in the CSP header
if [ -z "${ALLOWED_ALGORITHM_STORES}" ]; then
ALLOWED_ALGORITHM_STORES="*"
fi
# escape the slashes in the urls
ALLOWED_ALGORITHM_STORES=$(echo "$ALLOWED_ALGORITHM_STORES" | sed 's/\//\\\//g')
sed -i "s/<ALGORITHM_STORE_URLS>/$ALLOWED_ALGORITHM_STORES/g" /etc/nginx/nginx.conf

0 comments on commit 68dfa66

Please sign in to comment.