diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 0c86b2e58ec50..8b50fc38167d3 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -457,7 +457,7 @@ deprecation warning at startup. This setting cannot end in a slash (`/`). | experimental[] Set to `true` to allow browser code to access response body whenever request performed with user credentials. *Default:* `false` | `server.cors.allowOrigin:` - | experimental[] List of origins permitted to access resources. You must specify explicit hostnames and not use `*` for `server.cors.allowOrigin` when `server.cors.allowCredentials: true`. *Default:* "*" + | experimental[] List of origins permitted to access resources. You must specify explicit hostnames and not use `server.cors.allowOrigin: ["*"]` when `server.cors.allowCredentials: true`. *Default:* ["*"] | `server.compression.referrerWhitelist:` | Specifies an array of trusted hostnames, such as the {kib} host, or a reverse diff --git a/src/core/server/http/__snapshots__/http_config.test.ts.snap b/src/core/server/http/__snapshots__/http_config.test.ts.snap index 3337c30977a3e..9b667f888771e 100644 --- a/src/core/server/http/__snapshots__/http_config.test.ts.snap +++ b/src/core/server/http/__snapshots__/http_config.test.ts.snap @@ -40,7 +40,9 @@ Object { }, "cors": Object { "allowCredentials": false, - "allowOrigin": "*", + "allowOrigin": Array [ + "*", + ], "enabled": false, }, "customResponseHeaders": Object {}, diff --git a/src/core/server/http/http_config.test.ts b/src/core/server/http/http_config.test.ts index 190d0bd21ef5f..b71763e8a2e14 100644 --- a/src/core/server/http/http_config.test.ts +++ b/src/core/server/http/http_config.test.ts @@ -341,7 +341,7 @@ describe('cors', () => { }) ).toThrowErrorMatchingInlineSnapshot(` "[cors.allowOrigin]: types that failed validation: - - [cors.allowOrigin.0]: expected value to equal [*] + - [cors.allowOrigin.0]: array size is [0], but cannot be smaller than [1] - [cors.allowOrigin.1]: array size is [0], but cannot be smaller than [1]" `); }); @@ -364,14 +364,28 @@ describe('cors', () => { }); it('can be configured as "*" wildcard', () => { - expect(config.schema.validate({ cors: { allowOrigin: '*' } }).cors.allowOrigin).toBe('*'); + expect(config.schema.validate({ cors: { allowOrigin: ['*'] } }).cors.allowOrigin).toEqual([ + '*', + ]); + }); + + it('cannot mix wildcard "*" with valid URLs', () => { + expect( + () => + config.schema.validate({ cors: { allowOrigin: ['*', 'https://elastic.co'] } }).cors + .allowOrigin + ).toThrowErrorMatchingInlineSnapshot(` + "[cors.allowOrigin]: types that failed validation: + - [cors.allowOrigin.0.0]: expected URI with scheme [http|https]. + - [cors.allowOrigin.1.1]: expected value to equal [*]" + `); }); }); describe('credentials', () => { it('cannot use wildcard allowOrigin if "credentials: true"', () => { expect( () => - config.schema.validate({ cors: { allowCredentials: true, allowOrigin: '*' } }).cors + config.schema.validate({ cors: { allowCredentials: true, allowOrigin: ['*'] } }).cors .allowOrigin ).toThrowErrorMatchingInlineSnapshot( `"[cors]: Cannot specify wildcard origin \\"*\\" with \\"credentials: true\\". Please provide a list of allowed origins."` diff --git a/src/core/server/http/http_config.ts b/src/core/server/http/http_config.ts index 1825ce9b326a4..2bd296fe338ab 100644 --- a/src/core/server/http/http_config.ts +++ b/src/core/server/http/http_config.ts @@ -50,15 +50,18 @@ export const config = { enabled: schema.boolean({ defaultValue: false }), allowCredentials: schema.boolean({ defaultValue: false }), allowOrigin: schema.oneOf( - [schema.literal('*'), schema.arrayOf(hostURISchema, { minSize: 1 })], + [ + schema.arrayOf(hostURISchema, { minSize: 1 }), + schema.arrayOf(schema.literal('*'), { minSize: 1, maxSize: 1 }), + ], { - defaultValue: '*', + defaultValue: ['*'], } ), }, { validate(value) { - if (value.allowCredentials === true && value.allowOrigin === '*') { + if (value.allowCredentials === true && value.allowOrigin.includes('*')) { return 'Cannot specify wildcard origin "*" with "credentials: true". Please provide a list of allowed origins.'; } }, @@ -169,7 +172,7 @@ export class HttpConfig { public cors: { enabled: boolean; allowCredentials: boolean; - allowOrigin: '*' | string[]; + allowOrigin: string[]; }; public customResponseHeaders: Record; public maxPayload: ByteSizeValue; diff --git a/src/core/server/http/http_tools.test.ts b/src/core/server/http/http_tools.test.ts index 757f4f91686bb..962c2107513b5 100644 --- a/src/core/server/http/http_tools.test.ts +++ b/src/core/server/http/http_tools.test.ts @@ -197,7 +197,7 @@ describe('getServerOptions', () => { cors: { enabled: true, allowCredentials: false, - allowOrigin: '*', + allowOrigin: ['*'], }, }), {} as any, @@ -206,7 +206,7 @@ describe('getServerOptions', () => { expect(getServerOptions(httpConfig).routes?.cors).toEqual({ credentials: false, - origin: '*', + origin: ['*'], headers: ['Accept', 'Authorization', 'Content-Type', 'If-None-Match', 'kbn-xsrf'], }); });