summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/grumpy-sloths-fail.md30
-rw-r--r--packages/astro/src/cli/dev/index.ts1
-rw-r--r--packages/astro/src/cli/flags.ts6
-rw-r--r--packages/astro/src/cli/preview/index.ts1
-rw-r--r--packages/astro/src/core/config/schema.ts9
-rw-r--r--packages/astro/src/core/dev/container.ts4
-rw-r--r--packages/astro/src/core/preview/static-preview-server.ts1
-rw-r--r--packages/astro/src/types/public/config.ts21
8 files changed, 71 insertions, 2 deletions
diff --git a/.changeset/grumpy-sloths-fail.md b/.changeset/grumpy-sloths-fail.md
new file mode 100644
index 000000000..1a5e9b272
--- /dev/null
+++ b/.changeset/grumpy-sloths-fail.md
@@ -0,0 +1,30 @@
+---
+'astro': minor
+---
+
+Adds a new configuration option `server.allowedHosts` and CLI option `--allowed-hosts`.
+
+Now you can specify the hostnames that the dev and preview servers are allowed to respond to. This is useful for allowing additional subdomains, or running the dev server in a web container.
+
+`allowedHosts` checks the Host header on HTTP requests from browsers and if it doesn't match, it will reject the request to prevent CSRF and XSS attacks.
+
+```shell
+astro dev --allowed-hosts=foo.bar.example.com,bar.example.com
+```
+
+```shell
+astro preview --allowed-hosts=foo.bar.example.com,bar.example.com
+```
+
+```js
+// astro.config.mjs
+import {defineConfig} from "astro/config";
+
+export default defineConfig({
+ server: {
+ allowedHosts: ['foo.bar.example.com', 'bar.example.com']
+ }
+})
+```
+
+This feature is the same as [Vite's `server.allowHosts` configuration](https://vite.dev/config/server-options.html#server-allowedhosts).
diff --git a/packages/astro/src/cli/dev/index.ts b/packages/astro/src/cli/dev/index.ts
index 4bf888c43..d10d00059 100644
--- a/packages/astro/src/cli/dev/index.ts
+++ b/packages/astro/src/cli/dev/index.ts
@@ -20,6 +20,7 @@ export async function dev({ flags }: DevOptions) {
['--host <custom-address>', `Expose on a network IP address at <custom-address>`],
['--open', 'Automatically open the app in the browser on server start'],
['--force', 'Clear the content layer cache, forcing a full rebuild.'],
+ ['--allowed-hosts', 'Specify a comma-separated list of allowed hosts or allow any hostname.'],
['--help (-h)', 'See all available flags.'],
],
},
diff --git a/packages/astro/src/cli/flags.ts b/packages/astro/src/cli/flags.ts
index 7466fdda7..c283ec85e 100644
--- a/packages/astro/src/cli/flags.ts
+++ b/packages/astro/src/cli/flags.ts
@@ -25,6 +25,12 @@ export function flagsToAstroInlineConfig(flags: Flags): AstroInlineConfig {
typeof flags.host === 'string' || typeof flags.host === 'boolean' ? flags.host : undefined,
open:
typeof flags.open === 'string' || typeof flags.open === 'boolean' ? flags.open : undefined,
+ allowedHosts:
+ typeof flags.allowedHosts === 'string'
+ ? flags.allowedHosts.split(',')
+ : typeof flags.allowedHosts === 'boolean' && flags.allowedHosts === true
+ ? flags.allowedHosts
+ : [],
},
};
}
diff --git a/packages/astro/src/cli/preview/index.ts b/packages/astro/src/cli/preview/index.ts
index 468332ce3..9e0b88e11 100644
--- a/packages/astro/src/cli/preview/index.ts
+++ b/packages/astro/src/cli/preview/index.ts
@@ -18,6 +18,7 @@ export async function preview({ flags }: PreviewOptions) {
['--host', `Listen on all addresses, including LAN and public addresses.`],
['--host <custom-address>', `Expose on a network IP address at <custom-address>`],
['--open', 'Automatically open the app in the browser on server start'],
+ ['--allowed-hosts', 'Specify a comma-separated list of allowed hosts or allow any hostname.'],
['--help (-h)', 'See all available flags.'],
],
},
diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts
index 83546aeb9..82609e3b4 100644
--- a/packages/astro/src/core/config/schema.ts
+++ b/packages/astro/src/core/config/schema.ts
@@ -77,6 +77,7 @@ export const ASTRO_CONFIG_DEFAULTS = {
host: false,
port: 4321,
open: false,
+ allowedHosts: [],
},
integrations: [],
markdown: markdownConfigDefaults,
@@ -214,6 +215,10 @@ export const AstroConfigSchema = z.object({
.default(ASTRO_CONFIG_DEFAULTS.server.host),
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
headers: z.custom<OutgoingHttpHeaders>().optional(),
+ allowedHosts: z
+ .union([z.array(z.string()), z.literal(true)])
+ .optional()
+ .default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts),
})
.default({}),
),
@@ -718,6 +723,10 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: string) {
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
headers: z.custom<OutgoingHttpHeaders>().optional(),
streaming: z.boolean().optional().default(true),
+ allowedHosts: z
+ .union([z.array(z.string()), z.literal(true)])
+ .optional()
+ .default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts),
})
.optional()
.default({}),
diff --git a/packages/astro/src/core/dev/container.ts b/packages/astro/src/core/dev/container.ts
index d1570f492..c984fae7d 100644
--- a/packages/astro/src/core/dev/container.ts
+++ b/packages/astro/src/core/dev/container.ts
@@ -56,7 +56,7 @@ export async function createContainer({
const {
base,
- server: { host, headers, open: serverOpen },
+ server: { host, headers, open: serverOpen, allowedHosts },
} = settings.config;
// serverOpen = true, isRestart = false
@@ -92,7 +92,7 @@ export async function createContainer({
const mode = inlineConfig?.mode ?? 'development';
const viteConfig = await createVite(
{
- server: { host, headers, open },
+ server: { host, headers, open, allowedHosts },
optimizeDeps: {
include: rendererClientEntries,
},
diff --git a/packages/astro/src/core/preview/static-preview-server.ts b/packages/astro/src/core/preview/static-preview-server.ts
index 855506ef9..13798ef99 100644
--- a/packages/astro/src/core/preview/static-preview-server.ts
+++ b/packages/astro/src/core/preview/static-preview-server.ts
@@ -36,6 +36,7 @@ export default async function createStaticPreviewServer(
port: settings.config.server.port,
headers: settings.config.server.headers,
open: settings.config.server.open,
+ allowedHosts: settings.config.server.allowedHosts
},
plugins: [vitePluginAstroPreview(settings)],
});
diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts
index f9023343e..cbb1cfe5f 100644
--- a/packages/astro/src/types/public/config.ts
+++ b/packages/astro/src/types/public/config.ts
@@ -68,6 +68,27 @@ export type ServerConfig = {
*/
port?: number;
+
+ /**
+ * @name server.allowedHosts
+ * @type {string[] | true}
+ * @default `[]`
+ * @version 5.4.0
+ * @description
+ *
+ * A list of hostnames that Astro is allowed to respond to. When the value is set to `true`, any
+ * hostname is allowed.
+ *
+ * ```js
+ * {
+ * server: {
+ * allowedHosts: ['staging.example.com', 'qa.example.com']
+ * }
+ * }
+ * ```
+ */
+ allowedHosts?: string[] | true;
+
/**
* @name server.headers
* @typeraw {OutgoingHttpHeaders}