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

@moritzheiber
Copy link
Contributor Author

@lafriks I refactored the routine according to your suggestions 👍

@@ -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
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
Copy link
Member

lafriks commented Jul 23, 2017

LGTM

sapk
sapk approved these changes Jul 24, 2017
@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.
Development

Successfully merging this pull request may close these issues.

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