Skip to content

Commit

Permalink
Add config properties for HTTP security headers (#97158)
Browse files Browse the repository at this point in the history
  • Loading branch information
jportner authored Apr 19, 2021
1 parent b7a9b84 commit 978f5ec
Show file tree
Hide file tree
Showing 31 changed files with 501 additions and 86 deletions.
2 changes: 1 addition & 1 deletion config/kibana.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#server.publicBaseUrl: ""

# The maximum payload size in bytes for incoming server requests.
#server.maxPayloadBytes: 1048576
#server.maxPayload: 1048576

# The Kibana server's name. This is used for display purposes.
#server.name: "your-hostname"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [CspConfig](./kibana-plugin-core-server.cspconfig.md) &gt; [disableEmbedding](./kibana-plugin-core-server.cspconfig.disableembedding.md)

## CspConfig.disableEmbedding property

<b>Signature:</b>

```typescript
readonly disableEmbedding: boolean;
```
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The constructor for this class is marked as internal. Third-party code should no
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [DEFAULT](./kibana-plugin-core-server.cspconfig.default.md) | <code>static</code> | <code>CspConfig</code> | |
| [disableEmbedding](./kibana-plugin-core-server.cspconfig.disableembedding.md) | | <code>boolean</code> | |
| [header](./kibana-plugin-core-server.cspconfig.header.md) | | <code>string</code> | |
| [rules](./kibana-plugin-core-server.cspconfig.rules.md) | | <code>string[]</code> | |
| [strict](./kibana-plugin-core-server.cspconfig.strict.md) | | <code>boolean</code> | |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ICspConfig](./kibana-plugin-core-server.icspconfig.md) &gt; [disableEmbedding](./kibana-plugin-core-server.icspconfig.disableembedding.md)

## ICspConfig.disableEmbedding property

Whether or not embedding (using iframes) should be allowed by the CSP. If embedding is disabled \*and\* no custom rules have been defined, a restrictive 'frame-ancestors' rule will be added to the default CSP rules.

<b>Signature:</b>

```typescript
readonly disableEmbedding: boolean;
```
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface ICspConfig

| Property | Type | Description |
| --- | --- | --- |
| [disableEmbedding](./kibana-plugin-core-server.icspconfig.disableembedding.md) | <code>boolean</code> | Whether or not embedding (using iframes) should be allowed by the CSP. If embedding is disabled \*and\* no custom rules have been defined, a restrictive 'frame-ancestors' rule will be added to the default CSP rules. |
| [header](./kibana-plugin-core-server.icspconfig.header.md) | <code>string</code> | The CSP rules in a formatted directives string for use in a <code>Content-Security-Policy</code> header. |
| [rules](./kibana-plugin-core-server.icspconfig.rules.md) | <code>string[]</code> | The CSP rules used for Kibana. |
| [strict](./kibana-plugin-core-server.icspconfig.strict.md) | <code>boolean</code> | Specify whether browsers that do not support CSP should be able to use Kibana. Use <code>true</code> to block and <code>false</code> to allow. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may cause the server to run out of memory.

Default value: The one set in the kibana.yml config file under the parameter `server.maxPayloadBytes`<!-- -->.
Default value: The one set in the kibana.yml config file under the parameter `server.maxPayload`<!-- -->.

<b>Signature:</b>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface RouteConfigOptionsBody
| Property | Type | Description |
| --- | --- | --- |
| [accepts](./kibana-plugin-core-server.routeconfigoptionsbody.accepts.md) | <code>RouteContentType &#124; RouteContentType[] &#124; string &#124; string[]</code> | A string or an array of strings with the allowed mime types for the endpoint. Use this settings to limit the set of allowed mime types. Note that allowing additional mime types not listed above will not enable them to be parsed, and if parse is true, the request will result in an error response.<!-- -->Default value: allows parsing of the following mime types: \* application/json \* application/\*+json \* application/octet-stream \* application/x-www-form-urlencoded \* multipart/form-data \* text/\* |
| [maxBytes](./kibana-plugin-core-server.routeconfigoptionsbody.maxbytes.md) | <code>number</code> | Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may cause the server to run out of memory.<!-- -->Default value: The one set in the kibana.yml config file under the parameter <code>server.maxPayloadBytes</code>. |
| [maxBytes](./kibana-plugin-core-server.routeconfigoptionsbody.maxbytes.md) | <code>number</code> | Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may cause the server to run out of memory.<!-- -->Default value: The one set in the kibana.yml config file under the parameter <code>server.maxPayload</code>. |
| [output](./kibana-plugin-core-server.routeconfigoptionsbody.output.md) | <code>typeof validBodyOutput[number]</code> | The processed payload format. The value must be one of: \* 'data' - the incoming payload is read fully into memory. If parse is true, the payload is parsed (JSON, form-decoded, multipart) based on the 'Content-Type' header. If parse is false, a raw Buffer is returned. \* 'stream' - the incoming payload is made available via a Stream.Readable interface. If the payload is 'multipart/form-data' and parse is true, field values are presented as text while files are provided as streams. File streams from a 'multipart/form-data' upload will also have a hapi property containing the filename and headers properties. Note that payload streams for multipart payloads are a synthetic interface created on top of the entire multipart content loaded into memory. To avoid loading large multipart payloads into memory, set parse to false and handle the multipart payload in the handler using a streaming parser (e.g. pez).<!-- -->Default value: 'data', unless no validation.body is provided in the route definition. In that case the default is 'stream' to alleviate memory pressure. |
| [parse](./kibana-plugin-core-server.routeconfigoptionsbody.parse.md) | <code>boolean &#124; 'gunzip'</code> | Determines if the incoming payload is processed or presented raw. Available values: \* true - if the request 'Content-Type' matches the allowed mime types set by allow (for the whole payload as well as parts), the payload is converted into an object when possible. If the format is unknown, a Bad Request (400) error response is sent. Any known content encoding is decoded. \* false - the raw payload is returned unmodified. \* 'gunzip' - the raw payload is returned unmodified after any known content encoding is decoded.<!-- -->Default value: true, unless no validation.body is provided in the route definition. In that case the default is false to alleviate memory pressure. |

2 changes: 1 addition & 1 deletion docs/maps/trouble-shooting.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ image::maps/images/inspector.png[]
** Ensure your geospatial field is searchable and aggregatable.
** If your geospatial field type does not match your Elasticsearch mapping, click the *Refresh* button to refresh the field list from Elasticsearch.
* Index patterns with thousands of fields can exceed the default maximum payload size.
Increase <<settings, `server.maxPayloadBytes`>> for large index patterns.
Increase <<settings, `server.maxPayload`>> for large index patterns.

[float]
==== Features are not displayed
Expand Down
59 changes: 56 additions & 3 deletions docs/setup/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ which may cause a delay before pages start being served.
Set to `false` to disable Console. *Default: `true`*

| `cpu.cgroup.path.override:`
| deprecated:[7.10.0,"This setting will no longer be supported as of 8.0."]
| deprecated:[7.10.0,"In 8.0 and later, this setting will no longer be supported."]
This setting has been renamed to
<<ops-cGroupOverrides-cpuPath,`ops.cGroupOverrides.cpuPath`>>.

| `cpuacct.cgroup.path.override:`
| deprecated:[7.10.0,"This setting will no longer be supported as of 8.0."]
| deprecated:[7.10.0,"In 8.0 and later, this setting will no longer be supported."]
This setting has been renamed to
<<ops-cGroupOverrides-cpuAcctPath, `ops.cGroupOverrides.cpuAcctPath`>>.

Expand Down Expand Up @@ -473,7 +473,7 @@ confident your server can hold this many objects in memory.
| The maximum byte size of a saved objects import that the {kib} server will accept.
This setting exists to prevent the {kib} server from runnning out of memory when handling
a large import payload. Note that this setting overrides the more general
<<server-maxPayloadBytes, `server.maxPayloadBytes`>> for saved object imports only.
<<server-maxPayload, `server.maxPayload`>> for saved object imports only.
*Default: `26214400`*

|[[server-basePath]] `server.basePath:`
Expand Down Expand Up @@ -504,6 +504,55 @@ deprecation warning at startup. This setting cannot end in a slash (`/`).
proxy sitting in front of it. This determines whether HTTP compression may be used for responses, based on the request `Referer` header.
This setting may not be used when <<server-compression, `server.compression.enabled`>> is set to `false`. *Default: `none`*


a| [[server-securityResponseHeaders-strictTransportSecurity]]
----
server.securityResponseHeaders:
strictTransportSecurity:
----
| Controls whether the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security[`Strict-Transport-Security`]
header is used in all responses to the client from the {kib} server, and specifies what value is used. Allowed values are any text value or
`null`. To disable, set to `null`. *Default:* `null`

a| [[server-securityResponseHeaders-xContentTypeOptions]]
----
server.securityResponseHeaders:
xContentTypeOptions:
----
| Controls whether the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options[`X-Content-Type-Options`] header is
used in all responses to the client from the {kib} server, and specifies what value is used. Allowed values are `nosniff` or `null`. To
disable, set to `null`. *Default:* `"nosniff"`

a| [[server-securityResponseHeaders-referrerPolicy]]
----
server.securityResponseHeaders:
referrerPolicy:
----
| Controls whether the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy[`Referrer-Policy`] header is used in all
responses to the client from the {kib} server, and specifies what value is used. Allowed values are `no-referrer`,
`no-referrer-when-downgrade`, `origin`, `origin-when-cross-origin`, `same-origin`, `strict-origin`, `strict-origin-when-cross-origin`,
`unsafe-url`, or `null`. To disable, set to `null`. *Default:* `"no-referrer-when-downgrade"`

a| [[server-securityResponseHeaders-permissionsPolicy]]
----
server.securityResponseHeaders:
permissionsPolicy:
----
| experimental[] Controls whether the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy[`Permissions-Policy`] header
is used in all responses to the client from the {kib} server, and specifies what value is used. Allowed values are any text value or `null`.
To disable, set to `null`. *Default:* `null`

a| [[server-securityResponseHeaders-disableEmbedding]]
----
server.securityResponseHeaders:
disableEmbedding:
----
| Controls whether the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy[`Content-Security-Policy`] and
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options[`X-Frame-Options`] headers are configured to disable embedding
{kib} in other webpages using iframes. When set to `true`, secure headers are used to disable embedding, which adds the `frame-ancestors:
'self'` directive to the `Content-Security-Policy` response header (if you are using the default CSP rules), and adds the `X-Frame-Options:
SAMEORIGIN` response header. *Default:* `false`

| `server.customResponseHeaders:` {ess-icon}
| Header names and values to
send on all responses to the client from the {kib} server. *Default: `{}`*
Expand All @@ -517,6 +566,10 @@ back end server. To allow remote users to connect, set the value to the IP addre
the <<server-socketTimeout, `server.socketTimeout`>> counter. *Default: `"120000"`*

|[[server-maxPayloadBytes]] `server.maxPayloadBytes:`
| deprecated:[7.13.0,"In 8.0 and later, this setting will no longer be supported."]
This setting has been renamed to <<server-maxPayload,`server.maxPayload`>>.

|[[server-maxPayload]] `server.maxPayload:`
| The maximum payload size in bytes
for incoming server requests. *Default: `1048576`*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ const createStartContractMock = () => {
supportedProtocols: ['TLSv1.1', 'TLSv1.2'],
truststoreConfigured: false,
},
securityResponseHeaders: {
strictTransportSecurity: 'NULL', // `null` values are coalesced to `"NULL"` strings
xContentTypeOptions: 'nosniff',
referrerPolicy: 'no-referrer-when-downgrade',
permissionsPolicyConfigured: false,
disableEmbedding: false,
},
xsrf: {
disableProtection: false,
allowlistConfigured: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ describe('CoreUsageDataService', () => {
"ipAllowlistConfigured": false,
},
"rewriteBasePath": false,
"securityResponseHeaders": Object {
"disableEmbedding": false,
"permissionsPolicyConfigured": false,
"referrerPolicy": "no-referrer-when-downgrade",
"strictTransportSecurity": "NULL",
"xContentTypeOptions": "nosniff",
},
"socketTimeout": 120000,
"ssl": Object {
"certificateAuthoritiesConfigured": false,
Expand Down
10 changes: 10 additions & 0 deletions src/core/server/core_usage_data/core_usage_data_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,16 @@ export class CoreUsageDataService implements CoreService<CoreUsageDataSetup, Cor
keystoreConfigured: isConfigured.record(http.ssl.keystore),
truststoreConfigured: isConfigured.record(http.ssl.truststore),
},
securityResponseHeaders: {
// ES does not index `null` and it cannot be searched, so we coalesce these to string values instead
strictTransportSecurity: http.securityResponseHeaders.strictTransportSecurity ?? 'NULL',
xContentTypeOptions: http.securityResponseHeaders.xContentTypeOptions ?? 'NULL',
referrerPolicy: http.securityResponseHeaders.referrerPolicy ?? 'NULL',
permissionsPolicyConfigured: isConfigured.string(
http.securityResponseHeaders.permissionsPolicy ?? undefined
),
disableEmbedding: http.securityResponseHeaders.disableEmbedding,
},
},

logging: {
Expand Down
7 changes: 7 additions & 0 deletions src/core/server/core_usage_data/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ export interface CoreConfigUsageData {
supportedProtocols: string[];
clientAuthentication: 'none' | 'optional' | 'required';
};
securityResponseHeaders: {
strictTransportSecurity: string;
xContentTypeOptions: string;
referrerPolicy: string;
permissionsPolicyConfigured: boolean;
disableEmbedding: boolean;
};
};

logging: {
Expand Down
19 changes: 19 additions & 0 deletions src/core/server/csp/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { config } from './config';

describe('config.validate()', () => {
test(`does not allow "disableEmbedding" to be set to true`, () => {
// This is intentionally not editable in the raw CSP config.
// Users should set `server.securityResponseHeaders.disableEmbedding` to control this config property.
expect(() => config.schema.validate({ disableEmbedding: true })).toThrowError(
'[disableEmbedding.0]: expected value to equal [false]'
);
});
});
3 changes: 3 additions & 0 deletions src/core/server/csp/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ export const config = {
}),
strict: schema.boolean({ defaultValue: true }),
warnLegacyBrowsers: schema.boolean({ defaultValue: true }),
disableEmbedding: schema.oneOf([schema.literal<boolean>(false)], { defaultValue: false }),
}),
};

export const FRAME_ANCESTORS_RULE = `frame-ancestors 'self'`; // only used by CspConfig when embedding is disabled
Loading

0 comments on commit 978f5ec

Please sign in to comment.