From d24c1da35e8d2f27c53cf0464d33304f35774bf5 Mon Sep 17 00:00:00 2001
From: jviide <jviide@iki.fi>
Date: Mon, 16 Jan 2023 03:00:44 +0200
Subject: [PATCH] feat: add security headers (with nuxt-security) (#1025)

---
 nuxt.config.ts | 25 ++++++++++++++++++++
 package.json   |  1 +
 pnpm-lock.yaml | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+)

diff --git a/nuxt.config.ts b/nuxt.config.ts
index 280142ff..c74d2546 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -25,6 +25,7 @@ export default defineNuxtConfig({
     '@vue-macros/nuxt',
     '@nuxtjs/i18n',
     '@nuxtjs/color-mode',
+    'nuxt-security',
     '~/modules/purge-comments',
     '~/modules/setup-components',
     '~/modules/build-env',
@@ -142,6 +143,30 @@ export default defineNuxtConfig({
       ],
     },
   },
+  security: {
+    headers: {
+      crossOriginEmbedderPolicy: false,
+      contentSecurityPolicy: {
+        value: {
+          'default-src': ['\'self\''],
+          'base-uri': ['\'self\''],
+          'connect-src': ['\'self\'', 'https:', 'http:', 'wss:', 'ws:'],
+          'font-src': ['\'self\''],
+          'form-action': ['\'none\''],
+          'frame-ancestors': ['\'none\''],
+          'img-src': ['\'self\'', 'https:', 'http:', 'data:'],
+          'media-src': ['\'self\'', 'https:', 'http:'],
+          'object-src': ['\'none\''],
+          'script-src': ['\'self\'', '\'unsafe-inline\''],
+          'script-src-attr': ['\'none\''],
+          'style-src': ['\'self\'', '\'unsafe-inline\''],
+          'upgrade-insecure-requests': true,
+        },
+        route: '/**',
+      },
+    },
+    rateLimiter: false,
+  },
   colorMode: { classSuffix: '' },
   i18n,
   pwa,
diff --git a/package.json b/package.json
index 0902cbeb..a1bd9159 100644
--- a/package.json
+++ b/package.json
@@ -100,6 +100,7 @@
     "jsdom": "^21.0.0",
     "lint-staged": "^13.1.0",
     "nuxt": "^3.0.0",
+    "nuxt-security": "^0.10.0",
     "postcss-nested": "^6.0.0",
     "prettier": "^2.8.2",
     "rollup-plugin-node-polyfills": "^0.2.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ebe347a1..9b1dc8de 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -94,6 +94,7 @@ importers:
       lru-cache: ^7.14.1
       masto: ^5.4.0
       nuxt: ^3.0.0
+      nuxt-security: ^0.10.0
       pinia: ^2.0.28
       postcss-nested: ^6.0.0
       prettier: ^2.8.2
@@ -198,6 +199,7 @@ importers:
       jsdom: 21.0.0
       lint-staged: 13.1.0
       nuxt: 3.0.0_iukboom6ndih5an6iafl45j2fe
+      nuxt-security: 0.10.0
       postcss-nested: 6.0.0
       prettier: 2.8.2
       rollup-plugin-node-polyfills: 0.2.1
@@ -2048,6 +2050,15 @@ packages:
       fastq: 1.15.0
     dev: true
 
+  /@nozomuikuta/h3-cors/0.1.8_defu@6.1.1:
+    resolution: {integrity: sha512-qWe2mUfnjxaBwTYKNM/9GrGK0nciyynn5Lk/sv8wYpKbloaoJFB98onBWMTotV5e/l8CCoelsr1oz4qYb7FdHg==}
+    peerDependencies:
+      defu: ^6.1.0
+      h3: ^0.8.6
+    dependencies:
+      defu: 6.1.1
+    dev: true
+
   /@nuxt-themes/docus/1.4.4_nuxt@3.0.0:
     resolution: {integrity: sha512-hVbFWD/2qotFVBQtau2eeR2g74k9lLdKZBU+voB2GTo6TbtC1SfVEUlh/KeSbR3DqvfIO1pNQnSTJFGvc4vMdg==}
     dependencies:
@@ -4570,6 +4581,13 @@ packages:
     resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
     dev: true
 
+  /basic-auth/2.0.1:
+    resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      safe-buffer: 5.1.2
+    dev: true
+
   /binary-extensions/2.2.0:
     resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
     engines: {node: '>=8'}
@@ -5182,6 +5200,10 @@ packages:
     hasBin: true
     dev: true
 
+  /cssfilter/0.0.10:
+    resolution: {integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==}
+    dev: true
+
   /cssnano-preset-default/5.2.13_postcss@8.4.19:
     resolution: {integrity: sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==}
     engines: {node: ^10 || ^12 || >=14.0}
@@ -7809,6 +7831,10 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /just-performance/4.3.0:
+    resolution: {integrity: sha512-L7RjvtJsL0QO8xFs5wEoDDzzJwoiowRw6Rn/GnvldlchS2JQr9wFYPiwZcDfrbbujEKqKN0tvENdbjXdYhDp5Q==}
+    dev: true
+
   /kleur/3.0.3:
     resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
     engines: {node: '>=6'}
@@ -7864,6 +7890,12 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
+  /limiter/2.1.0:
+    resolution: {integrity: sha512-361TYz6iay6n+9KvUUImqdLuFigK+K79qrUtBsXhJTLdH4rIt/r1y8r1iozwh8KbZNpujbFTSh74mJ7bwbAMOw==}
+    dependencies:
+      just-performance: 4.3.0
+    dev: true
+
   /lines-and-columns/1.2.4:
     resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
     dev: true
@@ -8284,6 +8316,10 @@ packages:
     resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
     dev: true
 
+  /memory-cache/0.2.0:
+    resolution: {integrity: sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==}
+    dev: true
+
   /memory-fs/0.5.0:
     resolution: {integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==}
     engines: {node: '>=4.3.0 <5.0.0 || >=5.10'}
@@ -8998,6 +9034,23 @@ packages:
       - vue
     dev: true
 
+  /nuxt-security/0.10.0:
+    resolution: {integrity: sha512-+wAnVnDcuOxzMsCd8fCmMCFULUmdzWICNEiggq/+F8fDmc5bs1v5JjbIttGIeV6FLL2Kpz3HfKuYfzCRBgRdQA==}
+    dependencies:
+      '@nozomuikuta/h3-cors': 0.1.8_defu@6.1.1
+      '@nuxt/kit': 3.0.0
+      basic-auth: 2.0.1
+      defu: 6.1.1
+      limiter: 2.1.0
+      memory-cache: 0.2.0
+      pathe: 1.0.0
+      xss: 1.0.14
+    transitivePeerDependencies:
+      - h3
+      - rollup
+      - supports-color
+    dev: true
+
   /nuxt/3.0.0:
     resolution: {integrity: sha512-RNlD78uv04ZiXWmlx9f1tnJfrqsYAWHU+4gbgOTQpIBmQzHWPWiox+fm/1m93iKfEd5sJi9TJUoXX5yBObVZYw==}
     engines: {node: ^14.16.0 || ^16.10.0 || ^17.0.0 || ^18.0.0 || ^19.0.0}
@@ -12802,6 +12855,15 @@ packages:
     engines: {node: '>=0.4.0'}
     dev: true
 
+  /xss/1.0.14:
+    resolution: {integrity: sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==}
+    engines: {node: '>= 0.10.0'}
+    hasBin: true
+    dependencies:
+      commander: 2.20.3
+      cssfilter: 0.0.10
+    dev: true
+
   /xxhashjs/0.2.2:
     resolution: {integrity: sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==}
     dependencies: