[7.x] Rename server.xsrf.whitelist to server.xsrf.allowlist (#84791) (#84861)

* 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:
Mikhail Shustov 2020-12-03 17:51:44 +03:00 committed by GitHub
parent 36a62c1f53
commit 645eae82b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 43 additions and 51 deletions

View file

@ -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`::

View file

@ -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`::

View file

@ -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:
|===

View file

@ -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 [],
},
}
`;

View file

@ -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: [],
},
},
});

View file

@ -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\\"",
]
`);
});

View file

@ -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,
];

View file

@ -99,7 +99,7 @@ const createStartContractMock = () => {
},
xsrf: {
disableProtection: false,
whitelistConfigured: false,
allowlistConfigured: false,
},
},
logging: {

View file

@ -182,8 +182,8 @@ describe('CoreUsageDataService', () => {
"truststoreConfigured": false,
},
"xsrf": Object {
"allowlistConfigured": false,
"disableProtection": false,
"whitelistConfigured": false,
},
},
"logging": Object {

View file

@ -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,

View file

@ -100,7 +100,7 @@ export interface CoreConfigUsageData {
};
xsrf: {
disableProtection: boolean;
whitelistConfigured: boolean;
allowlistConfigured: boolean;
};
requestId: {
allowFromAnyIp: boolean;

View file

@ -83,8 +83,8 @@ Object {
"truststore": Object {},
},
"xsrf": Object {
"allowlist": Array [],
"disableProtection": false,
"whitelist": Array [],
},
}
`;

View file

@ -60,7 +60,7 @@ configService.atPath.mockReturnValue(
compression: { enabled: true },
xsrf: {
disableProtection: true,
whitelist: [],
allowlist: [],
},
customResponseHeaders: {},
requestId: {

View file

@ -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"`
);
});

View file

@ -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[] };
/**

View file

@ -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 () => {

View file

@ -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({

View file

@ -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();

View file

@ -43,7 +43,7 @@ configService.atPath.mockReturnValue(
compression: { enabled: true },
xsrf: {
disableProtection: true,
whitelist: [],
allowlist: [],
},
customResponseHeaders: {},
requestId: {

View file

@ -409,7 +409,7 @@ export interface CoreConfigUsageData {
};
xsrf: {
disableProtection: boolean;
whitelistConfigured: boolean;
allowlistConfigured: boolean;
};
requestId: {
allowFromAnyIp: boolean;

View file

@ -65,7 +65,7 @@ export function getCoreUsageCollector(
},
xsrf: {
disableProtection: { type: 'boolean' },
whitelistConfigured: { type: 'boolean' },
allowlistConfigured: { type: 'boolean' },
},
requestId: {
allowFromAnyIp: { type: 'boolean' },

View file

@ -1391,7 +1391,7 @@
"disableProtection": {
"type": "boolean"
},
"whitelistConfigured": {
"allowlistConfigured": {
"type": "boolean"
}
}

View file

@ -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}`,