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

Only allow token authentication with 2FA enabled #2184

Merged
merged 6 commits into from
Jul 26, 2017

Conversation

moritzheiber
Copy link
Contributor

Fixes #1394

Previously, when a user had 2FA enabled they were still able to authenticate via HTTP(S) using their regular username and password. This PR makes token authentication mandatory for accounts with 2FA enabled.

} else {
_, err = models.GetTwoFactorByUID(authUser.ID)

if err == nil {
Copy link
Member

@lafriks lafriks Jul 19, 2017

Choose a reason for hiding this comment

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

You need to also check that if !models.IsErrTwoFactorNotEnrolled(err) and do ctx.Handle(http.StatusInternalServerError, "IsErrTwoFactorNotEnrolled", err) + return otherwise if there is some kind of unexpected error you will let user in and it will bypass 2fa

token, err := models.GetAccessTokenBySHA(authUsername)
if authUser == nil {
// Assume password is a token.
token, err := models.GetAccessTokenBySHA(authPasswd)
Copy link
Member

Choose a reason for hiding this comment

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

You need to also check if user models.GetUserByName(authUsername) returns correct user and validate that returned user.ID is equal to token.UID

@lafriks lafriks added type/bug topic/security Something leaks user information or is otherwise vulnerable. Should be fixed! labels Jul 19, 2017
@lafriks lafriks added this to the 1.2.0 milestone Jul 19, 2017
@moritzheiber
Copy link
Contributor Author

@lafriks I refactored the routine according to your suggestions 👍

@tboerger tboerger added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jul 20, 2017
@@ -167,13 +180,33 @@ func HTTP(ctx *context.Context) {
}
return
}

tokenUser, err := models.GetUserByID(token.UID)
Copy link
Member

Choose a reason for hiding this comment

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

No need to get user by ID, you can just compare authUser.ID != token.UID on line 190

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True!

if err != nil {
ctx.Handle(http.StatusInternalServerError, "GetUserByID", err)
if !models.IsErrTwoFactorNotEnrolled(err) {
Copy link
Member

Choose a reason for hiding this comment

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

I think better structure for this code would be:

				if err == nil {
					ctx.HandleText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page")
					return
				} else if !models.IsErrTwoFactorNotEnrolled(err) {
					ctx.Handle(http.StatusInternalServerError, "IsErrTwoFactorNotEnrolled", err)
					return
				}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, indeed

@lafriks
Copy link
Member

lafriks commented Jul 20, 2017

@moritzheiber few more optimizations needed and than from me it would be LG-TM

@moritzheiber
Copy link
Contributor Author

@lafriks Should be all there now

@Bwko
Copy link
Member

Bwko commented Jul 23, 2017

LGTM

@lafriks lafriks added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Jul 23, 2017
@lafriks
Copy link
Member

lafriks commented Jul 23, 2017

@moritzheiber I have tested and works as expected only thing that I found that does not match GitHub behaviour is that when 2FA is enabled it returns Invalid username or password even for valid password and from security perspective it is right thing to do. So I would recommend changing also Uers with two-factor authentication enabled cannot... to invalid credentials.

@moritzheiber
Copy link
Contributor Author

@lafriks The only grievance I'd have with that is that within Gitea that's completely undocumented. Nothing on the two-factor authentication page tells you that you need to create an application token in order to login while having 2FA enabled:

This is probably going to confuse a lot of people.

I know the response is probably the wrong time and place of conveying this, but as of right now it's the only one.

@lafriks
Copy link
Member

lafriks commented Jul 23, 2017

Maybe than add todo comment that later for security reasons response should be changed to invalid credentials than it would be LG-TM from me

@moritzheiber
Copy link
Contributor Author

@lafriks Done.

@lafriks lafriks added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Jul 23, 2017
@lafriks
Copy link
Member

lafriks commented Jul 23, 2017

LGTM

@sapk
Copy link
Member

sapk commented Jul 24, 2017

LGTM

@lunny
Copy link
Member

lunny commented Jul 26, 2017

make CI work

@lunny lunny merged commit 7e12aac into go-gitea:master Jul 26, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. topic/security Something leaks user information or is otherwise vulnerable. Should be fixed! type/bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Block password-only auth when 2FA is enabled
6 participants