-
Notifications
You must be signed in to change notification settings - Fork 2
Make sure that failed login attempts are returned as 401 Unauthorized #160
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
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great change! I think it makes sense to return a
401in all non-success cases here for security purposes.Here is a small suggestion and my thought process
To me this feels more correct semantically. The absence of a record, in my mind, is not really an error even though we want to translate it into a 401. The translation is more of an obfuscation similar to an actual error. This is as opposed to the alternatives:
The main reason this stands out to me is that we're reaching into the other abstraction layers and explicitly returning an error that is defined in
entity_api. Even though it's re-exported throughdomainit feels slightly like we're leaking concepts between the boundaries. I think that returning theErr(StatusCode::UNAUTHORIZED.into_response()feels more appropriate for the something theweblayer's responsibility. Theentity_apiand lower level constructs should, if possible, be returned from those layers and only translated inweb.For
Err(auth_error)I think we could just return that as it already includes the information and would be just a pass through. I may be totally wrong there.This is somewhat nit picky but I think it's important to try to maintain the boundaries if possible. Certainly open to your take and philosophy on the matter. In the end it's not really a blocker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@calebbourg Great suggestion Caleb. So for the Err case, it would either map to something that exists, or turn into a 500 internal server error if an error was raised that didn't map to something we anticipate.
The only risk here is that we are now exposing a security difference to the world on our front page. This conversation is public, this source code is public, so someone just needs to figure out how to trigger this situation and now they know a distinct difference. I've read a lot of informed thoughts about login forms and consistency if the highest value. They even recommend that we always respond with the same constant time whether there's a successful login vs an unsuccessful one because of this "having distinct knowledge" risk. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you and thank you for your thoughts as well!
I completely agree with all of the security implications.
I envision it either returning a
401in the case where the user queried doesn't exist (theOk(None)case and then ensuring thatauth_session.authenticate(creds.clone())returns an error from the lower layers that web translates to a401. Which would mean in all non-authenticated scenarios (error, user doesn't exist, etc.) we will always return a401.Let me know if that makes sense and if you think it's feasible.
It may already be accomplished here:
refactor-platform-rs/entity_api/src/user.rs
Lines 127 to 135 in 46355c6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll look into this a little more deeply this evening. Thanks for your thoughts.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@calebbourg It looks like I must provide an
Ok(None) => {}branch to satisfy thelet user = match auth_session.authenticate(creds.clone()).await {}…it's expected and if it's not there rustc complains.Hopefully I'm not completely misunderstanding what you're intending here.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jhodapp no worries! I may not be describing my suggestion very well.
My hypothesis is that the goal I outlined can be accomplished by something like this (adding comments):
Let me know if that helps clarify my thought process. I haven't tested the error translation yet and so it may be that either
authenticate_user()needs to be updated to actually return an error that theweblayer will automatically translate to a401or, if that isn't possible, leave the code like this for now.