Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow disabling xsrf protection per an endpoint #58717

Merged
merged 15 commits into from
Mar 3, 2020

Conversation

mshustov
Copy link
Contributor

@mshustov mshustov commented Feb 27, 2020

Summary

Closes #53823
This PR:

  • allows disabling xsrf protection per an endpoint for NP plugins with xsrfRequired: false
  • deprecates server.xsrf.whitelist. it meant to be used for IdP endpoints only, which we can switch to xsrfRequired: false

Checklist

For maintainers

Dev Docs

Route configuration allows to disable xsrf protection for destructive HTTP methods:

routet.get({ path: ..., validate: ..., options: { xsrfRequired: false } })

It meant to be used for IdP endpoints only, which we are going to refactor to disable xsrf requirement per a specific endpoint.
@mshustov mshustov added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:New Platform Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. v8.0.0 v7.7.0 labels Feb 27, 2020
@mshustov mshustov requested a review from a team as a code owner February 27, 2020 12:12
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-security (Team:Security)

@mshustov mshustov requested review from azasypkin and a team February 27, 2020 12:12
@@ -31,7 +31,11 @@ export const createXsrfPostAuthHandler = (config: HttpConfig): OnPostAuthHandler
const { whitelist, disableProtection } = config.xsrf;

return (request, response, toolkit) => {
if (disableProtection || whitelist.includes(request.route.path)) {
if (
disableProtection ||
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that we added server.xsrf.disableProtection in spalger#6 for testing purposes solely. I'm wondering if we want to collect all test-only API in the one document to have a better understanding of API surface in case of future refactoring. (in addition to --migrationgs.skip, /internal/saved_objects/_migrate etc)

if (has(settings, 'server.xsrf.whitelist')) {
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.'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joshdover what is the appropriate place to track v8 breaking changes after #40768 was closed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this doc: docs/migration/migrate_8_0.asciidoc

src/core/server/http/router/request.ts Outdated Show resolved Hide resolved
src/core/server/config/deprecation/core_deprecations.ts Outdated Show resolved Hide resolved
Comment on lines 153 to 162
const kibanaRouteState: KibanaRouteState = { xsrfRequired };

this.server.route({
handler: route.handler,
method: route.method,
path: route.path,
options: {
// Enforcing the comparison with true because plugins could overwrite the auth strategy by doing `options: { authRequired: authStrategy as any }`
auth: authRequired === true ? undefined : false,
app: kibanaRouteState,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: can't this be inlined to remove the local var?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, but I want to make sure that kibanaRouteState implements KibanaRouteState correctly.
This declaration doesn't show an error for unknown properties, for example:

app: { xsrfRequired } as KibanaRouteState

@azasypkin
Copy link
Member

ACK: reviewing...

Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, but I found one issue while testing with a real route. Thanks for the quick turnaround on this one!

src/core/server/config/deprecation/core_deprecations.ts Outdated Show resolved Hide resolved
src/core/server/http/router/route.ts Outdated Show resolved Hide resolved
src/core/server/http/router/request.ts Outdated Show resolved Hide resolved
Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, tested locally - worked perfectly!

Side note: maybe in the future we may not accept this option for "non-destructive" HTTP methods at compile-time so that xsrfRequired: true on GET wouldn't confuse API consumers, like you've done for body?: Method extends .....

@@ -147,16 +147,22 @@ export class HttpServer {
for (const route of router.getRoutes()) {
this.log.debug(`registering route handler for [${route.path}]`);
// Hapi does not allow payload validation to be specified for 'head' or 'get' requests
const validate = ['head', 'get'].includes(route.method) ? undefined : { payload: true };
const validate = isSafeMethod(route.method) ? undefined : { payload: true };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hapi doesn't support handlers for the head method hapijs/hapi#795

@mshustov mshustov merged commit 4226b6f into elastic:master Mar 3, 2020
@mshustov mshustov deleted the issue-53823-xsrf-per-router branch March 3, 2020 14:46
mshustov added a commit to mshustov/kibana that referenced this pull request Mar 3, 2020
* add xsrfRequired flag to a route definition interface

* update tests

* deprecate server.xsrf.whitelist

It meant to be used for IdP endpoints only, which we are going to refactor to disable xsrf requirement per a specific endpoint.

* update docs

* do not fail on manual KibanaRequest creation

* address comments

* update tests

* address comments

* make xsrfRequired available only for destructive methods

* update docs

* another isSafeMethod usage
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

mshustov added a commit that referenced this pull request Mar 3, 2020
* add xsrfRequired flag to a route definition interface

* update tests

* deprecate server.xsrf.whitelist

It meant to be used for IdP endpoints only, which we are going to refactor to disable xsrf requirement per a specific endpoint.

* update docs

* do not fail on manual KibanaRequest creation

* address comments

* update tests

* address comments

* make xsrfRequired available only for destructive methods

* update docs

* another isSafeMethod usage
@joshdover joshdover mentioned this pull request Nov 25, 2020
33 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! v7.7.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow HTTP routes to programmatically opt out of XSRF protection
6 participants