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

Users can reset their own password without specifying their current password #42807

Closed
kobelb opened this issue Aug 7, 2019 · 5 comments · Fixed by #43447
Closed

Users can reset their own password without specifying their current password #42807

kobelb opened this issue Aug 7, 2019 · 5 comments · Fixed by #43447
Assignees
Labels
bug Fixes for quality problems that affect the customer experience Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more!

Comments

@kobelb
Copy link
Contributor

kobelb commented Aug 7, 2019

Currently, users can reset their own password in Kibana without specifying their current password.

I believe this is occurring because when we try to set the credentials to be used

await server.plugins.security.getUser(
BasicCredentials.decorateRequest(request, username, password)
);

they're ignored, and we end up relying upon the credentials that were associated with the request in the security's plugins "auth handler".

@azasypkin should we consider augmenting the getUser function exposed by the security plugin

const getCurrentUser = async (request: KibanaRequest) => {
if (isSecurityFeatureDisabled()) {
return null;
}
return (await clusterClient
.asScoped(request)
.callAsCurrentUser('shield.authenticate')) as AuthenticatedUser;
};

to essentially what we do in the BaseAuthenticationProvider:

protected async getUser(request: KibanaRequest, authHeaders: Headers = {}) {
return (await this.options.client
.asScoped({ headers: { ...request.headers, ...authHeaders } })
.callAsCurrentUser('shield.authenticate')) as AuthenticatedUser;
}

@kobelb kobelb added bug Fixes for quality problems that affect the customer experience Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! labels Aug 7, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-security

@azasypkin
Copy link
Member

Amazing, thanks for discovering that @kobelb! Let me debug it a bit first.

@azasypkin
Copy link
Member

azasypkin commented Aug 7, 2019

they're ignored, and we end up relying upon the credentials that were associated with the request in the security's plugins "auth handler".

You're right, we have a request <---> auth headers cache in the core and headers from this cache take precedence over headers that request has.

And it seems to be correct behavior (e.g. in Kerberos case request will contain Authorization: Negotiate xxx, but authentication headers will provide Authorization: Bearer yyy).

I'm leaning towards using your proposed solution (.asScoped({ headers: { ...request.headers, ...authHeaders } }) ) as an immediate fix.

But as a long term fix I was planning to get rid of BasicCredentials and use authenticator.login to cover this case eventually:

authenticator.login(request, { 
  provider: 'basic',
  sessionMode: SessionMode.NotAllowed,
  value: { username, password }
});

That solution requires a new sessionMode property (or something like this) in ProviderLoginAttempt that is Allowed by default (login attempt can modify existing session or establish a new one) and NotAllowed (login attempt doesn't touch session at all) for this use case (at least that was an initial idea). This way getUser will always return user associated with the request as it does currently and should do in the future I believe. I didn't give it much thought yet though...

What do you think?

@kobelb
Copy link
Contributor Author

kobelb commented Aug 7, 2019

That solution requires a new sessionMode property (or something like this) in ProviderLoginAttempt that is Allowed by default (login attempt can modify existing session or establish a new one) and NotAllowed (login attempt doesn't touch session at all) for this use case (at least that was an initial idea). This way getUser will always return user associated with the request as it does currently and should do in the future I believe. I didn't give it much thought yet though...

I like it even better :)

@azasypkin
Copy link
Member

I like it even better :)

Good, I'll try go this path then!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Fixes for quality problems that affect the customer experience Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants