-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Andres Correa Casablanca <[email protected]>
- Loading branch information
Showing
11 changed files
with
1,047 additions
and
387 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
|
||
# build & cache artifacts | ||
**/.astro/ | ||
**/.sst/ | ||
**/dist/ | ||
**/generated/ | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,17 +13,7 @@ SPDX-License-Identifier: CC-BY-4.0 | |
|
||
## Introduction | ||
|
||
This library will help you to compute the subresource integrity hashes for your | ||
JS scripts and CSS stylesheets. | ||
|
||
It works by installing an Astro hook that runs once the build step is done. This | ||
hook performs 3 steps: | ||
1. Computes the Subresource Integrity hashes for your scripts and styles. | ||
2. Modifies the generated HTML to include the integrity hashes. | ||
3. In case you specified a filepath for your SRI hashes module, it will generate | ||
(or update) a module that exports the associated SRI hashes, so you can use | ||
them later for other purposes, such as configuring your | ||
`Content-Security-Policy` headers. | ||
Astro-Shield helps you to enhance the security of your Astro site. | ||
|
||
## How to install | ||
|
||
|
@@ -43,187 +33,19 @@ pnpm add --save-dev @kindspells/astro-shield | |
In your `astro.config.mjs` file: | ||
|
||
```javascript | ||
import { resolve } from 'node:path' | ||
|
||
import { defineConfig } from 'astro/config' | ||
import { shield } from '@kindspells/astro-shield' | ||
|
||
const rootDir = new URL('.', import.meta.url).pathname | ||
|
||
export default defineConfig({ | ||
integrations: [ | ||
shield({ | ||
sri: { | ||
// Enables SRI hashes generation for statically generated pages | ||
enableStatic: true, // true by default | ||
|
||
// Enables a middleware that generates SRI hashes for dynamically | ||
// generated pages | ||
enableMiddleware: false, // false by default | ||
|
||
// This is the path where we'll generate the module containing the SRI | ||
// hashes for your scripts and styles. There's no need to pass this | ||
// parameter if you don't need this data, but it can be useful to | ||
// configure your CSP policies. | ||
hashesModule: resolve(rootDir, 'src', 'utils', 'sriHashes.mjs'), | ||
|
||
// For SSR content, Cross-Origin scripts must be explicitly allow-listed | ||
// by URL in order to be allowed by the Content Security Policy. | ||
// | ||
// Defaults to [] | ||
scriptsAllowListUrls: [ | ||
'https://code.jquery.com/jquery-3.7.1.slim.min.js', | ||
], | ||
|
||
// For SSR content, Cross-Origin styles must be explicitly allow-listed | ||
// by URL in order to be allowed by the Content Security Policy. | ||
// | ||
// Defaults to [] | ||
stylesAllowListUrls: [ | ||
'https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css', | ||
], | ||
|
||
/** | ||
* Inline styles are usually considered unsafe because they could make it | ||
* easier for an attacker to inject CSS rules in dynamic pages. However, they | ||
* don't pose a serious security risk for _most_ static pages. | ||
* | ||
* You can disable this option in case you want to enforce a stricter policy. | ||
* | ||
* @type {'all' | 'static' | false} | ||
* | ||
* Defaults to 'all'. | ||
*/ | ||
allowInlineStyles: 'all', | ||
|
||
/** | ||
* Inline scripts are usually considered unsafe because they could make it | ||
* easier for an attacker to inject JS code in dynamic pages. However, they | ||
* don't pose a serious security risk for _most_ static pages. | ||
* | ||
* You can disable this option in case you want to enforce a stricter policy. | ||
* | ||
* @type {'all' | 'static' | false} | ||
* | ||
* Defaults to 'all'. | ||
*/ | ||
allowInlineScript: 'all', | ||
}, | ||
|
||
// - If set, it controls how the security headers will be generated in the | ||
// middleware. | ||
// - If not set, no security headers will be generated in the middleware. | ||
securityHeaders: { | ||
// For now, we can only control CSP headers, but we'll add more options | ||
// in the future. | ||
// - If set, it controls how the CSP (Content Security Policy) header will be | ||
// generated in the middleware. | ||
// - If not set, no CSP header will be generated in the middleware. | ||
contentSecurityPolicy: { | ||
// - If set, it controls the "default" CSP directives (they can be overriden | ||
// at runtime). | ||
// - If not set, the middleware will use a minimal set of default directives. | ||
cspDirectives: { | ||
'default-src': "'none'", | ||
} | ||
} | ||
} | ||
}) | ||
shield({}) | ||
] | ||
}) | ||
``` | ||
|
||
### Generating Content-Security-Policy Headers | ||
You can enable automated CSP headers generation by setting the option | ||
`securityHeaders.contentSecurityPolicy` (it can be an empty object if you don't | ||
need to customise any specific behavior, but it must be defined). | ||
Besides enabling CSP, you can also configure its directives to some extent, via | ||
the `cspDirectives` option. | ||
> [!IMPORTANT] | ||
> It is advisable to set the option `sriHashesModule` in case your dynamic pages | ||
> include static JS or CSS resources. | ||
> | ||
> Also, do not explicitly disable the `enableStatic_SRI` option if you want | ||
> support for those static assets). | ||
### Accessing metadata generated at build time | ||
Once you run `astro build`, `@kindspells/astro-shield` will analyse the static | ||
output and generate a new module that exports the SRI hashes, so you can use | ||
them in your CSP headers. | ||
Here you can see an example of how the generated module looks: | ||
```javascript | ||
// Do not edit this file manually | ||
|
||
export const inlineScriptHashes = /** @type {string[]} */ ([]) | ||
|
||
export const inlineStyleHashes = /** @type {string[]} */ ([ | ||
'sha256-VC84dQdO3Mo7nZIRaNTJgrqPQ0foHI8gdp/DS+e9/lk=', | ||
]) | ||
|
||
export const extScriptHashes = /** @type {string[]} */ ([ | ||
'sha256-+aSouJX5t2z1jleTbCvA9DS7+ag/F4e4ZpB/adun4Sg=', | ||
]) | ||
|
||
export const extStyleHashes = /** @type {string[]} */ ([ | ||
'sha256-iwd3GNfA+kImEozakD3ZZQSZ8VVb3MFBOhJH6dEMnDE=', | ||
]) | ||
|
||
export const perPageSriHashes = | ||
/** @type {Record<string, { scripts: string[]; styles: string [] }>} */ ({ | ||
'index.html': { | ||
scripts: [ | ||
'sha256-+aSouJX5t2z1jleTbCvA9DS7+ag/F4e4ZpB/adun4Sg=', | ||
], | ||
styles: [ | ||
'sha256-VC84dQdO3Mo7nZIRaNTJgrqPQ0foHI8gdp/DS+e9/lk=' | ||
], | ||
}, | ||
'about.html': { | ||
scripts: [ | ||
'sha256-+aSouJX5t2z1jleTbCvA9DS7+ag/F4e4ZpB/adun4Sg=', | ||
], | ||
styles: [ | ||
'sha256-iwd3GNfA+kImEozakD3ZZQSZ8VVb3MFBOhJH6dEMnDE=', | ||
], | ||
}, | ||
}) | ||
``` | ||
## Learn more | ||
|
||
> [!IMPORTANT] | ||
> If your website is very small or it relies on | ||
> [View Transitions](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API), | ||
> then it's best to rely on the `inlineScriptHashes`, `inlineStyleHashes`, | ||
> `extScriptHashes` and `extStyleHashes` values. | ||
> [!IMPORTANT] | ||
> If you don't rely on View Transitions and you care about minimising the size | ||
> of your CSP headers, then you can rely on the `perPageSriHashes` exported | ||
> value. | ||
## Known limitations | ||
- ⚠️ In case your SSR (dynamic) pages refer to static `.js` or `.css` files, and | ||
any of these resources change, then you will need to run the `astro build` | ||
command **two consecutive times** (Astro-Shield will emit a warning message | ||
telling you about it). | ||
- The SRI hashes will be regenerated only when running `astro build`. This means | ||
that if you need them to be up to date when you run `astro dev`, then you will | ||
have to manually run `astro build`. | ||
- In the context of Content-Security-Policy: When a script is loaded with a | ||
_static_ import rather than directly included with a `<script>` tag, having | ||
its hash present in the `script-src` directive is not enough to ensure that | ||
the browser will accept it. | ||
This means that, for now, it is advisable to add `'self'` to the `script-src` | ||
directive (adding `'strict-dynamic'` does not help either). | ||
- [Astro-Shield Documentation](https://astro-shield.kindspells.dev) | ||
|
||
## Other Relevant Guidelines | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.