NGINX for Mozilla HTTP Observatory
2023-10-23
Last edit: 2023-10-23
---------------------

Website security, whether in terms of cookies or HTTP headers, is still very important. A good way to measure the security of your website is with Mozilla Observatory.

This is a tool set up by Mozilla in the form of a website. It assigns a security rating based on predefined criteria, and documents configurations that can improve this rating.

For the technical part with NGINX, I've chosen to use [this website](/) as an example, which has obtained a satisfactory security rating.

## NGINX security

### HTTP to HTTPS redirection

The first thing to do with NGINX is to redirect HTTP traffic to an HTTPS port.

```nginx
server {
  listen 80;
  listen [::]:80;

  return 301 https://$host$request_uri;
}
```

The HTTP 301 status code is used to tell the browser to redirect to another URL.

### SSL parameters

```nginx
ssl_session_timeout 1d;

# Disable SSL session tickets
ssl_session_tickets off;

# Enable and verify SSL stapling
ssl_stapling on;
ssl_stapling_verify on;

# Stapling certificate
ssl_trusted_certificate /path/fullchain.pem;

# Specific DNS server for the resolver
resolver 1.1.1.1;
resolver_timeout 5s;
```

Enabling stapling reduces latency for the client. This is because the SSL certificate's validity status is checked by the server, not by the client browser. This information is then added to the certificate by the server.

### HTTP basics security headers

```nginx
# Instructs the browser to use HTTPS
add_header Strict-Transport-Security "max-age=63072000" always;

# Enables a cross-site scripting (XSS) protection feature
add_header X-XSS-Protection "1; mode=block";

# Disables resource content type guessing
add_header X-Content-Type-Options "nosniff";

# Controls how the Referer header is sent in requests
add_header Referrer-Policy "no-referrer";

# Defines the permissions for specific web features
add_header Permissions-Policy "microphone=(), geolocation=()";

# Disables embed iframe of this website on another website
add_header X-Frame-Options "DENY";
```

Also, another important point checked by Mozilla Observatory is the Content Security Policies. It is an added layer of security that helps to detect and mitigate certain types of attacks like XSS and data injection attacks.

### Dynamic Content Security Policies

```nginx
sub_filter_once off;
sub_filter nonce_value $ssl_session_id;

add_header Content-Security-Policy "default-src 'none'; font-src 'self'; style-src 'self'; media-src 'self'; frame-ancestors 'self'; base-uri 'none'; form-action 'none'; style-src-elem 'self' 'nonce-$ssl_session_id'; img-src 'self'; script-src 'self' 'unsafe-hashes' 'sha256-2daR3BDHUgNt2bWp/u+3CNDJtsIDrpz+22+QPnNNS5c='; connect-src 'self'";
```

`sub_filter` is a directive from the `ngx_http_sub_module` NGINX module. It is used to replace a string by a specific value in the HTTP response.

In effect, here I'm generating a random value with NGINX that will replace `nonce_value` associated with the `nonce` attribute placed, in our context, on HTML `
```

The CSP header in the HTTP response will therefore indicate that style tags with the `nonce` attribute and the value generated by NGINX are authorized. This allows certain CSS sources to be authorized.

Just like `sha256-2daR3BDHUgNt2bWp/u+3CNDJtsIDrpz+22+QPnNNS5c=` which represents and authorizes a JavaScript source to be loaded by the browser.