Skip to content

Commit 42f3644

Browse files
Gustedearl-warren
authored andcommitted
fix: disallow basic authorization when security keys are enrolled
- This unifies the security behavior of enrolling security keys with enrolling TOTP as a 2FA method. When TOTP is enrolled, you cannot use basic authorization (user:password) to make API request on behalf of the user, this is now also the case when you enroll security keys. - The usage of access tokens are the only method to make API requests on behalf of the user when a 2FA method is enrolled for the user. - Integration test added. (cherry picked from commit e6bbecb)
1 parent 1770117 commit 42f3644

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

services/auth/basic.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package auth
66

77
import (
8+
"errors"
89
"net/http"
910
"strings"
1011

@@ -132,6 +133,16 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore
132133
return nil, err
133134
}
134135

136+
hashWebAuthn, err := auth_model.HasWebAuthnRegistrationsByUID(req.Context(), u.ID)
137+
if err != nil {
138+
log.Error("HasWebAuthnRegistrationsByUID: %v", err)
139+
return nil, err
140+
}
141+
142+
if hashWebAuthn {
143+
return nil, errors.New("Basic authorization is not allowed while having security keys enrolled")
144+
}
145+
135146
if skipper, ok := source.Cfg.(LocalTwoFASkipper); !ok || !skipper.IsSkipLocalTwoFA() {
136147
if err := validateTOTP(req, u); err != nil {
137148
return nil, err

tests/integration/api_twofa_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"code.gitea.io/gitea/tests"
1616

1717
"github.com/pquerna/otp/totp"
18+
"github.com/stretchr/testify/assert"
1819
"github.com/stretchr/testify/require"
1920
)
2021

@@ -58,3 +59,24 @@ func TestAPITwoFactor(t *testing.T) {
5859
req.Header.Set("X-Forgejo-OTP", passcode)
5960
MakeRequest(t, req, http.StatusOK)
6061
}
62+
63+
func TestAPIWebAuthn(t *testing.T) {
64+
defer tests.PrepareTestEnv(t)()
65+
66+
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 32})
67+
unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{UserID: user.ID})
68+
69+
req := NewRequest(t, "GET", "/api/v1/user")
70+
req.SetBasicAuth(user.Name, "notpassword")
71+
72+
resp := MakeRequest(t, req, http.StatusUnauthorized)
73+
74+
type userResponse struct {
75+
Message string `json:"message"`
76+
}
77+
var userParsed userResponse
78+
79+
DecodeJSON(t, resp, &userParsed)
80+
81+
assert.EqualValues(t, "Basic authorization is not allowed while having security keys enrolled", userParsed.Message)
82+
}

0 commit comments

Comments
 (0)