diff options
| author | 2024-02-06 17:02:25 +0000 | |
|---|---|---|
| committer | 2024-02-06 22:32:25 +0530 | |
| commit | d68681b0606c9e0af79407ddab8dea5bbe18e557 (patch) | |
| tree | b7a2b225b8bc4ca28261ab0ce2f94c54befc9f95 /packages/integrations/netlify/src | |
| parent | d06f2b2f4936dfc2738807271bc5a01531cc9ae2 (diff) | |
| download | astro-d68681b0606c9e0af79407ddab8dea5bbe18e557.tar.gz astro-d68681b0606c9e0af79407ddab8dea5bbe18e557.tar.zst astro-d68681b0606c9e0af79407ddab8dea5bbe18e557.zip | |
feat(netlify): verification for edge middleware (#152)
* feat(netlify): verification for edge middleware
* add changeset
* remove unused folder
Diffstat (limited to 'packages/integrations/netlify/src')
| -rw-r--r-- | packages/integrations/netlify/src/index.ts | 9 | ||||
| -rw-r--r-- | packages/integrations/netlify/src/ssr-function.ts | 12 |
2 files changed, 18 insertions, 3 deletions
diff --git a/packages/integrations/netlify/src/index.ts b/packages/integrations/netlify/src/index.ts index e634c4ecc..63a17e7ab 100644 --- a/packages/integrations/netlify/src/index.ts +++ b/packages/integrations/netlify/src/index.ts @@ -6,6 +6,7 @@ import type { AstroConfig, AstroIntegration, RouteData } from 'astro'; import { AstroError } from 'astro/errors'; import { build } from 'esbuild'; import { appendFile, mkdir, readFile, rm, writeFile } from 'fs/promises'; +import type { Args } from "./ssr-function.js" const { version: packageVersion } = JSON.parse( await readFile(new URL('../package.json', import.meta.url), 'utf8') @@ -75,6 +76,8 @@ export default function netlifyIntegration( let outDir: URL; let rootDir: URL; let astroMiddlewareEntryPoint: URL | undefined = undefined; + // Secret used to verify that the caller is the astro-generated edge middleware and not a third-party + const middlewareSecret = crypto.randomUUID(); const ssrOutputDir = () => new URL('./.netlify/functions-internal/ssr/', rootDir); const middlewareOutputDir = () => new URL('.netlify/edge-functions/middleware/', rootDir); @@ -136,6 +139,7 @@ export default function netlifyIntegration( const next = () => { const { netlify, ...otherLocals } = ctx.locals; request.headers.set("x-astro-locals", trySerializeLocals(otherLocals)); + request.headers.set("x-astro-middleware-secret", "${middlewareSecret}"); return context.next(); }; @@ -270,6 +274,8 @@ export default function netlifyIntegration( 'See https://github.com/withastro/adapters/tree/main/packages/netlify#image-cdn for more.' ); } + + const edgeMiddleware = integrationConfig?.edgeMiddleware ?? false; setAdapter({ name: '@astrojs/netlify', @@ -277,8 +283,9 @@ export default function netlifyIntegration( exports: ['default'], adapterFeatures: { functionPerRoute: false, - edgeMiddleware: integrationConfig?.edgeMiddleware ?? false, + edgeMiddleware, }, + args: { middlewareSecret } satisfies Args, supportedAstroFeatures: { hybridOutput: 'stable', staticOutput: 'stable', diff --git a/packages/integrations/netlify/src/ssr-function.ts b/packages/integrations/netlify/src/ssr-function.ts index 57d945a3c..d6067fac1 100644 --- a/packages/integrations/netlify/src/ssr-function.ts +++ b/packages/integrations/netlify/src/ssr-function.ts @@ -6,11 +6,13 @@ import { applyPolyfills } from 'astro/app/node'; applyPolyfills(); // biome-ignore lint/complexity/noBannedTypes: safe to use in this case -export type Args = {}; +export interface Args { + middlewareSecret: string; +}; const clientAddressSymbol = Symbol.for('astro.clientAddress'); -export const createExports = (manifest: SSRManifest, _args: Args) => { +export const createExports = (manifest: SSRManifest, { middlewareSecret }: Args) => { const app = new App(manifest); function createHandler(integrationConfig: { @@ -27,7 +29,13 @@ export const createExports = (manifest: SSRManifest, _args: Args) => { let locals: Record<string, unknown> = {}; const astroLocalsHeader = request.headers.get('x-astro-locals'); + const middlewareSecretHeader = request.headers.get('x-astro-middleware-secret'); if (astroLocalsHeader) { + if (middlewareSecretHeader !== middlewareSecret) { + return new Response("Forbidden", { status: 403 }) + } + // hide the secret from the rest of user and library code + request.headers.delete('x-astro-middleware-secret'); locals = JSON.parse(astroLocalsHeader); } |
