mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* Rename server.xsrf.whitelist to server.xsrf.allowlist (#84791) * rename xsrd.whitelist to xsrf.allowlist * update docs * update telemetry schema * update kbn-config tests # Conflicts: # src/core/server/config/deprecation/core_deprecations.ts * Update core_deprecations.ts * miss import
This commit is contained in:
parent
36a62c1f53
commit
645eae82b7
23 changed files with 43 additions and 51 deletions
|
@ -62,7 +62,7 @@ For all APIs, you must use a request header. The {kib} APIs support the `kbn-xsr
|
|||
By default, you must use `kbn-xsrf` for all API calls, except in the following scenarios:
|
||||
|
||||
* The API endpoint uses the `GET` or `HEAD` operations
|
||||
* The path is whitelisted using the <<settings-xsrf-whitelist, `server.xsrf.whitelist`>> setting
|
||||
* The path is allowed using the <<settings-xsrf-allowlist, `server.xsrf.allowlist`>> setting
|
||||
* XSRF protections are disabled using the <<settings-xsrf-disableProtection, `server.xsrf.disableProtection`>> setting
|
||||
|
||||
`Content-Type: application/json`::
|
||||
|
|
|
@ -40,7 +40,7 @@ users interacting with APM APIs must have <<apm-app-api-user,sufficient privileg
|
|||
By default, you must use `kbn-xsrf` for all API calls, except in the following scenarios:
|
||||
|
||||
* The API endpoint uses the `GET` or `HEAD` operations
|
||||
* The path is whitelisted using the <<settings-xsrf-whitelist, `server.xsrf.whitelist`>> setting
|
||||
* The path is allowed using the <<settings-xsrf-allowlist, `server.xsrf.allowlist`>> setting
|
||||
* XSRF protections are disabled using the <<settings-xsrf-disableProtection, `server.xsrf.disableProtection`>> setting
|
||||
|
||||
`Content-Type: application/json`::
|
||||
|
|
|
@ -575,10 +575,10 @@ all http requests to https over the port configured as <<server-port, `server.po
|
|||
| An array of supported protocols with versions.
|
||||
Valid protocols: `TLSv1`, `TLSv1.1`, `TLSv1.2`, `TLSv1.3`. *Default: TLSv1.1, TLSv1.2, TLSv1.3*
|
||||
|
||||
| [[settings-xsrf-whitelist]] `server.xsrf.whitelist:`
|
||||
| [[settings-xsrf-allowlist]] `server.xsrf.allowlist:`
|
||||
| It is not recommended to disable protections for
|
||||
arbitrary API endpoints. Instead, supply the `kbn-xsrf` header.
|
||||
The <<settings-xsrf-whitelist, `server.xsrf.whitelist`>> setting requires the following format:
|
||||
The <<settings-xsrf-allowlist, `server.xsrf.allowlist`>> setting requires the following format:
|
||||
|
||||
|===
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ Object {
|
|||
},
|
||||
"uuid": undefined,
|
||||
"xsrf": Object {
|
||||
"allowlist": Array [],
|
||||
"disableProtection": false,
|
||||
"whitelist": Array [],
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
@ -56,8 +56,8 @@ Object {
|
|||
},
|
||||
"uuid": undefined,
|
||||
"xsrf": Object {
|
||||
"allowlist": Array [],
|
||||
"disableProtection": false,
|
||||
"whitelist": Array [],
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -96,7 +96,7 @@ describe('#get', () => {
|
|||
someNotSupportedValue: 'val',
|
||||
xsrf: {
|
||||
disableProtection: false,
|
||||
whitelist: [],
|
||||
allowlist: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -119,7 +119,7 @@ describe('#get', () => {
|
|||
someNotSupportedValue: 'val',
|
||||
xsrf: {
|
||||
disableProtection: false,
|
||||
whitelist: [],
|
||||
allowlist: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -82,12 +82,13 @@ describe('core deprecations', () => {
|
|||
|
||||
describe('xsrfDeprecation', () => {
|
||||
it('logs a warning if server.xsrf.whitelist is set', () => {
|
||||
const { messages } = applyCoreDeprecations({
|
||||
const { migrated, messages } = applyCoreDeprecations({
|
||||
server: { xsrf: { whitelist: ['/path'] } },
|
||||
});
|
||||
expect(migrated.server.xsrf.allowlist).toEqual(['/path']);
|
||||
expect(messages).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"It is not recommended to disable xsrf protections for API endpoints via [server.xsrf.whitelist]. It will be removed in 8.0 release. Instead, supply the \\"kbn-xsrf\\" header.",
|
||||
"\\"server.xsrf.whitelist\\" is deprecated and has been replaced by \\"server.xsrf.allowlist\\"",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
|
|
@ -38,16 +38,6 @@ const dataPathDeprecation: ConfigDeprecation = (settings, fromPath, log) => {
|
|||
return settings;
|
||||
};
|
||||
|
||||
const xsrfDeprecation: ConfigDeprecation = (settings, fromPath, log) => {
|
||||
if ((settings.server?.xsrf?.whitelist ?? []).length > 0) {
|
||||
log(
|
||||
'It is not recommended to disable xsrf protections for API endpoints via [server.xsrf.whitelist]. ' +
|
||||
'It will be removed in 8.0 release. Instead, supply the "kbn-xsrf" header.'
|
||||
);
|
||||
}
|
||||
return settings;
|
||||
};
|
||||
|
||||
const rewriteBasePathDeprecation: ConfigDeprecation = (settings, fromPath, log) => {
|
||||
if (has(settings, 'server.basePath') && !has(settings, 'server.rewriteBasePath')) {
|
||||
log(
|
||||
|
@ -116,6 +106,7 @@ const mapManifestServiceUrlDeprecation: ConfigDeprecation = (settings, fromPath,
|
|||
export const coreDeprecationProvider: ConfigDeprecationProvider = ({
|
||||
unusedFromRoot,
|
||||
renameFromRoot,
|
||||
rename,
|
||||
}) => [
|
||||
unusedFromRoot('savedObjects.indexCheckTimeout'),
|
||||
unusedFromRoot('server.xsrf.token'),
|
||||
|
@ -148,6 +139,7 @@ export const coreDeprecationProvider: ConfigDeprecationProvider = ({
|
|||
renameFromRoot('xpack.telemetry.url', 'telemetry.url'),
|
||||
renameFromRoot('cpu.cgroup.path.override', 'ops.cGroupOverrides.cpuPath'),
|
||||
renameFromRoot('cpuacct.cgroup.path.override', 'ops.cGroupOverrides.cpuAcctPath'),
|
||||
renameFromRoot('server.xsrf.whitelist', 'server.xsrf.allowlist'),
|
||||
unusedFromRoot('elasticsearch.preserveHost'),
|
||||
unusedFromRoot('elasticsearch.startupTimeout'),
|
||||
configPathDeprecation,
|
||||
|
@ -155,5 +147,4 @@ export const coreDeprecationProvider: ConfigDeprecationProvider = ({
|
|||
rewriteBasePathDeprecation,
|
||||
cspRulesDeprecation,
|
||||
mapManifestServiceUrlDeprecation,
|
||||
xsrfDeprecation,
|
||||
];
|
||||
|
|
|
@ -99,7 +99,7 @@ const createStartContractMock = () => {
|
|||
},
|
||||
xsrf: {
|
||||
disableProtection: false,
|
||||
whitelistConfigured: false,
|
||||
allowlistConfigured: false,
|
||||
},
|
||||
},
|
||||
logging: {
|
||||
|
|
|
@ -182,8 +182,8 @@ describe('CoreUsageDataService', () => {
|
|||
"truststoreConfigured": false,
|
||||
},
|
||||
"xsrf": Object {
|
||||
"allowlistConfigured": false,
|
||||
"disableProtection": false,
|
||||
"whitelistConfigured": false,
|
||||
},
|
||||
},
|
||||
"logging": Object {
|
||||
|
|
|
@ -180,7 +180,7 @@ export class CoreUsageDataService implements CoreService<void, CoreUsageDataStar
|
|||
},
|
||||
xsrf: {
|
||||
disableProtection: http.xsrf.disableProtection,
|
||||
whitelistConfigured: isConfigured.array(http.xsrf.whitelist),
|
||||
allowlistConfigured: isConfigured.array(http.xsrf.allowlist),
|
||||
},
|
||||
requestId: {
|
||||
allowFromAnyIp: http.requestId.allowFromAnyIp,
|
||||
|
|
|
@ -100,7 +100,7 @@ export interface CoreConfigUsageData {
|
|||
};
|
||||
xsrf: {
|
||||
disableProtection: boolean;
|
||||
whitelistConfigured: boolean;
|
||||
allowlistConfigured: boolean;
|
||||
};
|
||||
requestId: {
|
||||
allowFromAnyIp: boolean;
|
||||
|
|
|
@ -83,8 +83,8 @@ Object {
|
|||
"truststore": Object {},
|
||||
},
|
||||
"xsrf": Object {
|
||||
"allowlist": Array [],
|
||||
"disableProtection": false,
|
||||
"whitelist": Array [],
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -60,7 +60,7 @@ configService.atPath.mockReturnValue(
|
|||
compression: { enabled: true },
|
||||
xsrf: {
|
||||
disableProtection: true,
|
||||
whitelist: [],
|
||||
allowlist: [],
|
||||
},
|
||||
customResponseHeaders: {},
|
||||
requestId: {
|
||||
|
|
|
@ -165,15 +165,15 @@ test('uses os.hostname() as default for server.name', () => {
|
|||
expect(validated.name).toEqual('kibana-hostname');
|
||||
});
|
||||
|
||||
test('throws if xsrf.whitelist element does not start with a slash', () => {
|
||||
test('throws if xsrf.allowlist element does not start with a slash', () => {
|
||||
const httpSchema = config.schema;
|
||||
const obj = {
|
||||
xsrf: {
|
||||
whitelist: ['/valid-path', 'invalid-path'],
|
||||
allowlist: ['/valid-path', 'invalid-path'],
|
||||
},
|
||||
};
|
||||
expect(() => httpSchema.validate(obj)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[xsrf.whitelist.1]: must start with a slash"`
|
||||
`"[xsrf.allowlist.1]: must start with a slash"`
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ export const config = {
|
|||
),
|
||||
xsrf: schema.object({
|
||||
disableProtection: schema.boolean({ defaultValue: false }),
|
||||
whitelist: schema.arrayOf(
|
||||
allowlist: schema.arrayOf(
|
||||
schema.string({ validate: match(/^\//, 'must start with a slash') }),
|
||||
{ defaultValue: [] }
|
||||
),
|
||||
|
@ -142,7 +142,7 @@ export class HttpConfig {
|
|||
public ssl: SslConfig;
|
||||
public compression: { enabled: boolean; referrerWhitelist?: string[] };
|
||||
public csp: ICspConfig;
|
||||
public xsrf: { disableProtection: boolean; whitelist: string[] };
|
||||
public xsrf: { disableProtection: boolean; allowlist: string[] };
|
||||
public requestId: { allowFromAnyIp: boolean; ipAllowlist: string[] };
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,7 @@ const actualVersion = pkg.version;
|
|||
const versionHeader = 'kbn-version';
|
||||
const xsrfHeader = 'kbn-xsrf';
|
||||
const nameHeader = 'kbn-name';
|
||||
const whitelistedTestPath = '/xsrf/test/route/whitelisted';
|
||||
const allowlistedTestPath = '/xsrf/test/route/whitelisted';
|
||||
const xsrfDisabledTestPath = '/xsrf/test/route/disabled';
|
||||
const kibanaName = 'my-kibana-name';
|
||||
const setupDeps = {
|
||||
|
@ -63,7 +63,7 @@ describe('core lifecycle handlers', () => {
|
|||
customResponseHeaders: {
|
||||
'some-header': 'some-value',
|
||||
},
|
||||
xsrf: { disableProtection: false, whitelist: [whitelistedTestPath] },
|
||||
xsrf: { disableProtection: false, allowlist: [allowlistedTestPath] },
|
||||
requestId: {
|
||||
allowFromAnyIp: true,
|
||||
ipAllowlist: [],
|
||||
|
@ -179,7 +179,7 @@ describe('core lifecycle handlers', () => {
|
|||
}
|
||||
);
|
||||
((router as any)[method.toLowerCase()] as RouteRegistrar<any>)<any, any, any>(
|
||||
{ path: whitelistedTestPath, validate: false },
|
||||
{ path: allowlistedTestPath, validate: false },
|
||||
(context, req, res) => {
|
||||
return res.ok({ body: 'ok' });
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ describe('core lifecycle handlers', () => {
|
|||
});
|
||||
|
||||
it('accepts whitelisted requests without either an xsrf or version header', async () => {
|
||||
await getSupertest(method.toLowerCase(), whitelistedTestPath).expect(200, 'ok');
|
||||
await getSupertest(method.toLowerCase(), allowlistedTestPath).expect(200, 'ok');
|
||||
});
|
||||
|
||||
it('accepts requests on a route with disabled xsrf protection', async () => {
|
||||
|
|
|
@ -58,7 +58,7 @@ describe('xsrf post-auth handler', () => {
|
|||
|
||||
describe('non destructive methods', () => {
|
||||
it('accepts requests without version or xsrf header', () => {
|
||||
const config = createConfig({ xsrf: { whitelist: [], disableProtection: false } });
|
||||
const config = createConfig({ xsrf: { allowlist: [], disableProtection: false } });
|
||||
const handler = createXsrfPostAuthHandler(config);
|
||||
const request = forgeRequest({ method: 'get', headers: {} });
|
||||
|
||||
|
@ -74,7 +74,7 @@ describe('xsrf post-auth handler', () => {
|
|||
|
||||
describe('destructive methods', () => {
|
||||
it('accepts requests with xsrf header', () => {
|
||||
const config = createConfig({ xsrf: { whitelist: [], disableProtection: false } });
|
||||
const config = createConfig({ xsrf: { allowlist: [], disableProtection: false } });
|
||||
const handler = createXsrfPostAuthHandler(config);
|
||||
const request = forgeRequest({ method: 'post', headers: { 'kbn-xsrf': 'xsrf' } });
|
||||
|
||||
|
@ -88,7 +88,7 @@ describe('xsrf post-auth handler', () => {
|
|||
});
|
||||
|
||||
it('accepts requests with version header', () => {
|
||||
const config = createConfig({ xsrf: { whitelist: [], disableProtection: false } });
|
||||
const config = createConfig({ xsrf: { allowlist: [], disableProtection: false } });
|
||||
const handler = createXsrfPostAuthHandler(config);
|
||||
const request = forgeRequest({ method: 'post', headers: { 'kbn-version': 'some-version' } });
|
||||
|
||||
|
@ -102,7 +102,7 @@ describe('xsrf post-auth handler', () => {
|
|||
});
|
||||
|
||||
it('returns a bad request if called without xsrf or version header', () => {
|
||||
const config = createConfig({ xsrf: { whitelist: [], disableProtection: false } });
|
||||
const config = createConfig({ xsrf: { allowlist: [], disableProtection: false } });
|
||||
const handler = createXsrfPostAuthHandler(config);
|
||||
const request = forgeRequest({ method: 'post' });
|
||||
|
||||
|
@ -121,7 +121,7 @@ describe('xsrf post-auth handler', () => {
|
|||
});
|
||||
|
||||
it('accepts requests if protection is disabled', () => {
|
||||
const config = createConfig({ xsrf: { whitelist: [], disableProtection: true } });
|
||||
const config = createConfig({ xsrf: { allowlist: [], disableProtection: true } });
|
||||
const handler = createXsrfPostAuthHandler(config);
|
||||
const request = forgeRequest({ method: 'post', headers: {} });
|
||||
|
||||
|
@ -134,9 +134,9 @@ describe('xsrf post-auth handler', () => {
|
|||
expect(result).toEqual('next');
|
||||
});
|
||||
|
||||
it('accepts requests if path is whitelisted', () => {
|
||||
it('accepts requests if path is allowlisted', () => {
|
||||
const config = createConfig({
|
||||
xsrf: { whitelist: ['/some-path'], disableProtection: false },
|
||||
xsrf: { allowlist: ['/some-path'], disableProtection: false },
|
||||
});
|
||||
const handler = createXsrfPostAuthHandler(config);
|
||||
const request = forgeRequest({ method: 'post', headers: {}, path: '/some-path' });
|
||||
|
@ -152,7 +152,7 @@ describe('xsrf post-auth handler', () => {
|
|||
|
||||
it('accepts requests if xsrf protection on a route is disabled', () => {
|
||||
const config = createConfig({
|
||||
xsrf: { whitelist: [], disableProtection: false },
|
||||
xsrf: { allowlist: [], disableProtection: false },
|
||||
});
|
||||
const handler = createXsrfPostAuthHandler(config);
|
||||
const request = forgeRequest({
|
||||
|
|
|
@ -29,12 +29,12 @@ const XSRF_HEADER = 'kbn-xsrf';
|
|||
const KIBANA_NAME_HEADER = 'kbn-name';
|
||||
|
||||
export const createXsrfPostAuthHandler = (config: HttpConfig): OnPostAuthHandler => {
|
||||
const { whitelist, disableProtection } = config.xsrf;
|
||||
const { allowlist, disableProtection } = config.xsrf;
|
||||
|
||||
return (request, response, toolkit) => {
|
||||
if (
|
||||
disableProtection ||
|
||||
whitelist.includes(request.route.path) ||
|
||||
allowlist.includes(request.route.path) ||
|
||||
request.route.options.xsrfRequired === false
|
||||
) {
|
||||
return toolkit.next();
|
||||
|
|
|
@ -43,7 +43,7 @@ configService.atPath.mockReturnValue(
|
|||
compression: { enabled: true },
|
||||
xsrf: {
|
||||
disableProtection: true,
|
||||
whitelist: [],
|
||||
allowlist: [],
|
||||
},
|
||||
customResponseHeaders: {},
|
||||
requestId: {
|
||||
|
|
|
@ -409,7 +409,7 @@ export interface CoreConfigUsageData {
|
|||
};
|
||||
xsrf: {
|
||||
disableProtection: boolean;
|
||||
whitelistConfigured: boolean;
|
||||
allowlistConfigured: boolean;
|
||||
};
|
||||
requestId: {
|
||||
allowFromAnyIp: boolean;
|
||||
|
|
|
@ -65,7 +65,7 @@ export function getCoreUsageCollector(
|
|||
},
|
||||
xsrf: {
|
||||
disableProtection: { type: 'boolean' },
|
||||
whitelistConfigured: { type: 'boolean' },
|
||||
allowlistConfigured: { type: 'boolean' },
|
||||
},
|
||||
requestId: {
|
||||
allowFromAnyIp: { type: 'boolean' },
|
||||
|
|
|
@ -1391,7 +1391,7 @@
|
|||
"disableProtection": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"whitelistConfigured": {
|
||||
"allowlistConfigured": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions)
|
|||
(pluginDir) =>
|
||||
`--plugin-path=${path.resolve(__dirname, 'fixtures', 'plugins', pluginDir)}`
|
||||
),
|
||||
`--server.xsrf.whitelist=${JSON.stringify(getAllExternalServiceSimulatorPaths())}`,
|
||||
`--server.xsrf.allowlist=${JSON.stringify(getAllExternalServiceSimulatorPaths())}`,
|
||||
...(ssl
|
||||
? [
|
||||
`--elasticsearch.hosts=${servers.elasticsearch.protocol}://${servers.elasticsearch.hostname}:${servers.elasticsearch.port}`,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue