Skip to content

Commit 39f927a

Browse files
authored
Add additional security headers to nginx config (#1906)
Related tiny-pilot/tinypilot-pro#1593 This PR addresses the following precautionary web security considerations from tiny-pilot/tinypilot-pro#1591 (comment): - [`Content-Security-Policy` (CSP) header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) not set (i.e., prevent XSS) - [`X-Frame-Options` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options) not set (i.e., prevent clickjacking) - <s>[`Set-Cookie` header](https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/Cookies#secure) without secure flag</s> - Only applicable to HTTPS connections - [`Cross-Origin-Resource-Policy` (CORP) header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cross-Origin_Resource_Policy) not set (i.e., prevent [Spectre](https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)) vulnerability) - <s>[`Cross-Origin-Embedder-Policy` (COEP) header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cross-Origin-Embedder-Policy) not set</s> - Only applicable to HTTPS connections - <s>[`Cross-Origin-Opener-Policy` (COOP) header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cross-Origin-Opener-Policy) not set</s> - Only applicable to HTTPS connections - <s>[`Permissions-Policy` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Permissions-Policy) not set</s> - Only applicable to HTTPS connections - [`Server` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Server) reveals Nginx version info - <s>[`Strict-Transport-Security` (HSTS) header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security) not set</s> - Only applicable to HTTPS connections - [`X-Content-Type-Options` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options) not set (i.e., prevent MIME type sniffing) Notes: 1. We've added a Content Security Policy that allows inline JavaScript and CSS via the `unsafe-inline` flag. However, [the docs warn against this](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP#inline_javascript) by saying that allowing inline JavaScript defeats much of the purpose of CSP. Our use of "inline JavaScript" is a result of not using a JavaScript build pipeline for the sake of keeping frontend development as simple as possible. Even with the use of `unsafe-inline`, I still think our CSP is adding value via the [`default-src` directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/default-src) by restricting all resources to the same origin (i.e., `self`). 1. Our new Content Security Policy restricts the use of `data:` URLs. So I've converted our inline dot cursor image into a static image file. 1. This PR defines Nginx request headers and response headers into separate config files (located at `/etc/nginx/snippets/`). This allows us to easily redefine headers (via the `include` directive) when an Nginx config block needs to add additional headers. 1. This PR removes an unused legacy Nginx config file (i.e., `debian-pkg/usr/share/tinypilot/nginx.conf`). <a data-ca-tag href="https://codeapprove.com/pr/tiny-pilot/tinypilot/1906"><img src="https://codeapprove.com/external/github-tag-allbg.png" alt="Review on CodeApprove" /></a>
1 parent 964a43e commit 39f927a

File tree

7 files changed

+48
-58
lines changed

7 files changed

+48
-58
lines changed

app/static/css/cursors.css

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
}
1616

1717
*[cursor="dot"] > * {
18-
cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAb0lEQVQ4T9WSQQ4AMQRFuZfju5cJKcG0adNduyOer3yE/5NJTlOY8yUAABGZc4hWGvUZDIiZiygRWZxhBw3qQB9ZGzis4FLpCNypeRNXDcWHQP3Dbty+VWWuzuELuzJAwEO+nHAcfWm5XNwN2z0NHyeAUAvGKOgOAAAAAElFTkSuQmCC")
19-
6 6,
20-
auto !important;
18+
cursor: url("/img/dot-cursor.png") 6 6, auto !important;
2119
}
2220

2321
*[cursor="pointer"] > * {

app/static/img/dot-cursor.png

168 Bytes
Loading

debian-pkg/debian/tinypilot.postinst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ if [[ ! -L "${TINYPILOT_USTREAMER_OVERRIDES_FILE}" ]]; then
149149
"${TINYPILOT_USTREAMER_OVERRIDES_FILE}"
150150
fi
151151

152+
# Add NGINX snippets.
153+
cp \
154+
/usr/share/tinypilot/nginx_request_headers.conf \
155+
/etc/nginx/snippets/request-headers.conf
156+
cp \
157+
/usr/share/tinypilot/nginx_response_headers.conf \
158+
/etc/nginx/snippets/response-headers.conf
159+
152160
# Disable default NGINX server.
153161
rm -f \
154162
/etc/nginx/sites-enabled/default

debian-pkg/usr/share/tinypilot/nginx.conf

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
proxy_set_header Host $http_host;
2+
proxy_set_header X-Real-IP $remote_addr;
3+
proxy_set_header X-Scheme $scheme;
4+
proxy_set_header X-Forwarded-Proto $scheme;
5+
proxy_set_header X-Forwarded-Port $server_port;
6+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Set Content Security Policy (CSP).
2+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP
3+
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'";
4+
5+
# Prevent clickjacking.
6+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options
7+
add_header X-Frame-Options SAMEORIGIN;
8+
9+
# Prevent MIME type sniffing.
10+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options
11+
add_header X-Content-Type-Options nosniff;
12+
13+
# Set Cross-Origin Resource Policy (CORP).
14+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cross-Origin_Resource_Policy
15+
add_header Cross-Origin-Resource-Policy same-origin;

debian-pkg/usr/share/tinypilot/templates/tinypilot.conf.j2

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,26 @@ server {
2020

2121
index index.html;
2222

23+
# Prevent NGINX from revealing its version number.
24+
server_tokens off;
25+
2326
proxy_buffers 16 16k;
2427
proxy_buffer_size 16k;
25-
proxy_set_header Host $host;
26-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2728
proxy_http_version 1.1;
2829

30+
include /etc/nginx/snippets/request-headers.conf;
31+
include /etc/nginx/snippets/response-headers.conf;
32+
2933
error_page 502 /502.html;
3034

3135
location /socket.io {
3236
proxy_pass http://tinypilot;
3337
proxy_set_header Upgrade $http_upgrade;
3438
proxy_set_header Connection "Upgrade";
35-
# Since this is a connection upgrade, we don't inherit the settings from
36-
# above. We need these so that nginx forwards requests properly to
37-
# Flask-SocketIO.
38-
# See: https://github.com/miguelgrinberg/Flask-SocketIO/issues/1501#issuecomment-802082048
39-
proxy_set_header Host $http_host;
40-
proxy_set_header X-Forwarded-Host $http_host;
41-
proxy_set_header X-Forwarded-Proto $scheme;
39+
40+
# Redefine request headers, as they've been overwritten in this block.
41+
# See https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
42+
include /etc/nginx/snippets/request-headers.conf;
4243
}
4344
location /state {
4445
proxy_pass http://ustreamer;
@@ -56,12 +57,10 @@ server {
5657
proxy_pass http://janus-ws;
5758
proxy_set_header Upgrade $http_upgrade;
5859
proxy_set_header Connection "Upgrade";
59-
proxy_set_header Host $http_host;
60-
proxy_set_header X-Real-IP $remote_addr;
61-
proxy_set_header X-Scheme $scheme;
62-
proxy_set_header X-Forwarded-Proto $scheme;
63-
proxy_set_header X-Forwarded-Port $server_port;
64-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
60+
61+
# Redefine request headers, as they've been overwritten in this block.
62+
# See https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
63+
include /etc/nginx/snippets/request-headers.conf;
6564
}
6665
location / {
6766
proxy_pass http://tinypilot;
@@ -77,6 +76,10 @@ server {
7776
# to the `Last-Modified` header, so we make that seem recent.
7877
add_header Last-Modified $date_gmt;
7978
add_header Cache-Control 'public, max-age=10s';
79+
80+
# Redefine response headers, as they've been overwritten in this block.
81+
# See https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
82+
include /etc/nginx/snippets/response-headers.conf;
8083
}
8184
location ~* ^/.+\.(jpg|jpeg|png|ico)$ {
8285
root "/opt/tinypilot/app/static";

0 commit comments

Comments
 (0)