Skip to content

Commit

Permalink
feat: ssg script hashes support
Browse files Browse the repository at this point in the history
  • Loading branch information
Baroshem committed Oct 11, 2023
1 parent 4942b07 commit 644deee
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface ModuleOptions {
csrf: CsrfOptions | false;
nonce: NonceOptions | false;
removeLoggers?: RemoveOptions | false;
ssg?: Ssg;
}
```

Expand Down Expand Up @@ -108,6 +109,9 @@ security: {
consoleType: ['log', 'debug'],
include: [/\.[jt]sx?$/, /\.vue\??/],
exclude: [/node_modules/, /\.git/]
},
ssg: {
hashScripts: true
}
}
```
Expand Down
12 changes: 12 additions & 0 deletions docs/content/1.documentation/2.headers/1.csp.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,18 @@ This will result in following code being added to your static app `<head>` tag:
ℹ Read more about this [here](https://content-security-policy.com/examples/meta/).
::

By default, Nuxt Security will generate script hashes for you. If you do not want this functionality you can disable it like following:

```ts
export default defineNuxtConfig({
security: {
ssg: {
hashScripts: false
}
}
})
```

## `Nonce support`

To further increase CSP security, you can use a [nonce-based strict csp](https://web.dev/strict-csp/#what-is-a-strict-content-security-policy).
Expand Down
5 changes: 4 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@
"@nuxtlabs/github-module": "^1.6.3",
"@nuxtjs/plausible": "^0.2.1",
"nuxt": "^3.5.3"
}
},
"resolutions": {
"string-width": "4.2.3"
}
}
3 changes: 3 additions & 0 deletions src/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,8 @@ export const defaultSecurityConfig = (serverlUrl: string): ModuleOptions => ({
consoleType: ['log', 'debug'],
include: [/\.[jt]sx?$/, /\.vue\??/],
exclude: [/node_modules/, /\.git/]
},
ssg: {
hashScripts: true
}
})
5 changes: 3 additions & 2 deletions src/runtime/nitro/plugins/02-cspSsg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ interface NuxtRenderHTMLContext {
bodyAppend: string[]
}

const moduleOptions = useRuntimeConfig().security as ModuleOptions

export default <NitroAppPlugin> function (nitro) {
nitro.hooks.hook('render:html', (html: NuxtRenderHTMLContext, { event }: { event: H3Event }) => {
// Content Security Policy
const moduleOptions = useRuntimeConfig().security as ModuleOptions

if (!isContentSecurityPolicyEnabled(event, moduleOptions)) {
return
Expand Down Expand Up @@ -60,7 +61,7 @@ export default <NitroAppPlugin> function (nitro) {
}

const tagPolicies = defu(policies) as ContentSecurityPolicyValue
if (scriptHashes.length > 0) {
if (scriptHashes.length > 0 && moduleOptions.ssg?.hashScripts) {
// Remove '""'
tagPolicies['script-src'] = (tagPolicies['script-src'] ?? []).concat(scriptHashes)
}
Expand Down
5 changes: 5 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import type { Options as RemoveOptions } from 'unplugin-remove/types'
import { SecurityHeaders } from './headers'
import { AllowedHTTPMethods, BasicAuth, CorsOptions, NonceOptions, RateLimiter, RequestSizeLimiter, XssValidator } from './middlewares'

export type Ssg = {
hashScripts?: boolean;
};

export interface ModuleOptions {
headers: SecurityHeaders | false;
requestSizeLimiter: RequestSizeLimiter | false;
Expand All @@ -17,6 +21,7 @@ export interface ModuleOptions {
csrf: CsrfOptions | false;
nonce: NonceOptions | false;
removeLoggers?: RemoveOptions | false;
ssg?: Ssg;
}

export interface NuxtSecurityRouteRules {
Expand Down

0 comments on commit 644deee

Please sign in to comment.