Skip to content

checkCredentials() force it to be an affirmative yes! #16395

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

Closed

Conversation

weaverryan
Copy link
Member

Q A
Bug fix? no
New feature? no
BC breaks? no (because 2.8 isn't released)
Deprecations? no
Tests pass? yes
Fixed tickets n/a
License MIT
Doc PR n/a

This changes GuardAuthenticatorInterface::checkCredentials(): you now must return true in order for authentication to pass.

Before: You could do nothing (i.e. return null) and authentication would pass. You threw an AuthenticationException to cause a failure.

New: You must return true for authentication to pass. If you do nothing, we will throw a BadCredentialsException on your behalf. You can still throw your own exception.

This was a suggestion at symfony_live to make things more secure. I think it makes sense.

…s(): you now *must* return true in order for authentication to pass.

This was a suggestion at symfony_live to make things more secure: you must opt *into*
authentication passing - you can't do nothing in this method and make authentication pass.
$guardAuthenticator->checkCredentials($token->getCredentials(), $user);
if (true !== $guardAuthenticator->checkCredentials($token->getCredentials(), $user)) {
throw new BadCredentialsException(sprintf('Authentication failed because %s::checkCredentials() did not return true', get_class($guardAuthenticator)));
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Only }, it's standard

@weaverryan
Copy link
Member Author

updated!

@sstok
Copy link
Contributor

sstok commented Oct 31, 2015

👍 for this change.

@fabpot
Copy link
Member

fabpot commented Oct 31, 2015

Thank you @weaverryan.

@fabpot fabpot closed this in 64917c7 Oct 31, 2015
@weaverryan weaverryan deleted the check_credentials_affirmative branch October 31, 2015 17:14
@linaori
Copy link
Contributor

linaori commented Nov 19, 2015

I disagree with this PR, I understand the issue but this is really a user error and returning a boolean won't improve security here. You'd have to keep track of any errors thrown and you cannot do return false; in the end as this would always make it fail. You cannot do return true; in the end either because It would still yield the same result as without a boolean.

Result:

  • Additionally to throwing an exception, I would have to keep track of the result in a boolean because I have to return the success state.
  • This results in me putting return true; in the bottom of the function because I won't bother keeping track if I already throw exceptions.

With the above stated, I consider this change to be useless as it only adds an additional requirement which makes it more complex to get it working in the first place. If a developer really makes a mistake, his (unti)test should catch that and fail.

Could this be reverted perhaps?

@patrick-mcdougle
Copy link
Contributor

As the person who brought it up, I thank you for considering and making this change.

@nicolas-grekas
Copy link
Member

@iltar this looks like defensive programming. Of course it's not required, defensive programming is never required. But still, it allows one to write safer code by default. I see the benefit of it. If the downside is adding/managing a return true, I'd personally balance my preference for the defensive programming argument. Why don't you?

@linaori
Copy link
Contributor

linaori commented Nov 19, 2015

The current check is true !== that means that people who do test their code properly will have to add a non-meaningful return statement.

If the check were to be changed to false ===, people can opt-in and still return false. I don't see how this would make it safer though, if you don't throw an exception and forget to update your result, it will still fail. This will again come back to the point where this is a user error (probably because it lacks tests).

It also works differently than the usercheckers now. checkPreAuth and checkPostAuth also rely on throwing exceptions only. If this isn't reverted, the behavior of the user checks should imo be the same.

@weaverryan
Copy link
Member Author

The return statement is meaningful: you return true to pass checkCredentials, else it fails. The method acts like an areCredentialsValid() method.

Additionally to throwing an exception, I would have to keep track of the result in a boolean because I have to return the success state.

Why would you need to keep track of the state? If you know access should be denied, return false; immediately. If you know access should be granted, return true immediately. This is the same as before: if you knew access should be denied, you threw an exception. If you know access should be granted, you returned (null). With both, you have an easy way to exit from the function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants