Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix: trim whitespace from API tokens#19814

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletionscoderd/httpmw/apikey.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -730,13 +730,14 @@ func APITokenFromRequest(r *http.Request) string {
// Check Authorization: Bearer <token> header (case-insensitive per RFC 6750)
authHeader := r.Header.Get("Authorization")
if strings.HasPrefix(strings.ToLower(authHeader), "bearer ") {
return authHeader[7:] // Skip "Bearer " (7 characters)
// Skip "Bearer " (7 characters) and trim surrounding whitespace
return strings.TrimSpace(authHeader[7:])
}

// Check access_token query parameter
accessToken := r.URL.Query().Get("access_token")
if accessToken != "" {
return accessToken
returnstrings.TrimSpace(accessToken)
}

return ""
Expand Down
32 changes: 8 additions & 24 deletionscoderd/httpmw/rfc6750_extended_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,6 +20,8 @@ import (
)

// TestOAuth2BearerTokenSecurityBoundaries tests RFC 6750 security boundaries
//
//nolint:tparallel,paralleltest // Subtests share a DB; run sequentially to avoid Windows DB cleanup flake.
func TestOAuth2BearerTokenSecurityBoundaries(t *testing.T) {
t.Parallel()

Expand All@@ -41,8 +43,6 @@ func TestOAuth2BearerTokenSecurityBoundaries(t *testing.T) {
})

t.Run("TokenIsolation", func(t *testing.T) {
t.Parallel()

// Create middleware
middleware := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
DB: db,
Expand DownExpand Up@@ -78,8 +78,6 @@ func TestOAuth2BearerTokenSecurityBoundaries(t *testing.T) {
})

t.Run("CrossTokenAttempts", func(t *testing.T) {
t.Parallel()

middleware := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
DB: db,
})
Expand All@@ -101,8 +99,6 @@ func TestOAuth2BearerTokenSecurityBoundaries(t *testing.T) {
})

t.Run("TimingAttackResistance", func(t *testing.T) {
t.Parallel()

middleware := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
DB: db,
})
Expand DownExpand Up@@ -150,6 +146,8 @@ func TestOAuth2BearerTokenSecurityBoundaries(t *testing.T) {
}

// TestOAuth2BearerTokenMalformedHeaders tests handling of malformed Bearer headers per RFC 6750
//
//nolint:tparallel,paralleltest // Subtests share a DB; run sequentially to avoid Windows DB cleanup flake.
func TestOAuth2BearerTokenMalformedHeaders(t *testing.T) {
t.Parallel()

Expand DownExpand Up@@ -215,8 +213,6 @@ func TestOAuth2BearerTokenMalformedHeaders(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()

req := httptest.NewRequest("GET", "/test", nil)
req.Header.Set("Authorization", test.authHeader)
rec := httptest.NewRecorder()
Expand All@@ -234,6 +230,8 @@ func TestOAuth2BearerTokenMalformedHeaders(t *testing.T) {
}

// TestOAuth2BearerTokenPrecedence tests token extraction precedence per RFC 6750
//
//nolint:tparallel,paralleltest // Subtests share a DB; run sequentially to avoid Windows DB cleanup flake.
func TestOAuth2BearerTokenPrecedence(t *testing.T) {
t.Parallel()

Expand All@@ -257,8 +255,6 @@ func TestOAuth2BearerTokenPrecedence(t *testing.T) {
}))

t.Run("CookieTakesPrecedenceOverBearer", func(t *testing.T) {
t.Parallel()

req := httptest.NewRequest("GET", "/test", nil)
// Set both cookie and Bearer header - cookie should take precedence
req.AddCookie(&http.Cookie{
Expand All@@ -274,8 +270,6 @@ func TestOAuth2BearerTokenPrecedence(t *testing.T) {
})

t.Run("QueryParameterTakesPrecedenceOverBearer", func(t *testing.T) {
t.Parallel()

// Set both query parameter and Bearer header - query should take precedence
u, _ := url.Parse("/test")
q := u.Query()
Expand All@@ -292,8 +286,6 @@ func TestOAuth2BearerTokenPrecedence(t *testing.T) {
})

t.Run("BearerHeaderFallback", func(t *testing.T) {
t.Parallel()

// Only set Bearer header - should be used as fallback
req := httptest.NewRequest("GET", "/test", nil)
req.Header.Set("Authorization", "Bearer "+validToken)
Expand All@@ -305,8 +297,6 @@ func TestOAuth2BearerTokenPrecedence(t *testing.T) {
})

t.Run("AccessTokenQueryParameterFallback", func(t *testing.T) {
t.Parallel()

// Only set access_token query parameter - should be used as fallback
u, _ := url.Parse("/test")
q := u.Query()
Expand All@@ -322,8 +312,6 @@ func TestOAuth2BearerTokenPrecedence(t *testing.T) {
})

t.Run("MultipleAuthMethodsShouldNotConflict", func(t *testing.T) {
t.Parallel()

// RFC 6750 says clients shouldn't send tokens in multiple ways,
// but if they do, we should handle it gracefully by using precedence
u, _ := url.Parse("/test")
Expand All@@ -348,6 +336,8 @@ func TestOAuth2BearerTokenPrecedence(t *testing.T) {
}

// TestOAuth2WWWAuthenticateCompliance tests WWW-Authenticate header compliance with RFC 6750
//
//nolint:tparallel,paralleltest // Subtests share a DB; run sequentially to avoid Windows DB cleanup flake.
func TestOAuth2WWWAuthenticateCompliance(t *testing.T) {
t.Parallel()

Expand All@@ -363,8 +353,6 @@ func TestOAuth2WWWAuthenticateCompliance(t *testing.T) {
}))

t.Run("UnauthorizedResponse", func(t *testing.T) {
t.Parallel()

req := httptest.NewRequest("GET", "/test", nil)
req.Header.Set("Authorization", "Bearer invalid-token")
rec := httptest.NewRecorder()
Expand All@@ -383,8 +371,6 @@ func TestOAuth2WWWAuthenticateCompliance(t *testing.T) {
})

t.Run("ExpiredTokenResponse", func(t *testing.T) {
t.Parallel()

// Create an expired API key
_, expiredToken := dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
Expand All@@ -406,8 +392,6 @@ func TestOAuth2WWWAuthenticateCompliance(t *testing.T) {
})

t.Run("InsufficientScopeResponse", func(t *testing.T) {
t.Parallel()

// For this test, we'll test with an invalid token to trigger the middleware's
// error handling which does set WWW-Authenticate headers for 403 responses
// In practice, insufficient scope errors would be handled by RBAC middleware
Expand Down
14 changes: 2 additions & 12 deletionscoderd/httpmw/rfc6750_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,8 @@ import (

// TestRFC6750BearerTokenAuthentication tests that RFC 6750 bearer tokens work correctly
// for authentication, including both Authorization header and access_token query parameter methods.
//
//nolint:tparallel,paralleltest // Subtests share a DB; run sequentially to avoid Windows DB cleanup flake.
func TestRFC6750BearerTokenAuthentication(t *testing.T) {
t.Parallel()

Expand All@@ -44,8 +46,6 @@ func TestRFC6750BearerTokenAuthentication(t *testing.T) {
})

t.Run("AuthorizationBearerHeader", func(t *testing.T) {
t.Parallel()

req := httptest.NewRequest("GET", "/test", nil)
req.Header.Set("Authorization", "Bearer "+token)

Expand All@@ -57,8 +57,6 @@ func TestRFC6750BearerTokenAuthentication(t *testing.T) {
})

t.Run("AccessTokenQueryParameter", func(t *testing.T) {
t.Parallel()

req := httptest.NewRequest("GET", "/test?access_token="+url.QueryEscape(token), nil)

rw := httptest.NewRecorder()
Expand All@@ -69,8 +67,6 @@ func TestRFC6750BearerTokenAuthentication(t *testing.T) {
})

t.Run("BearerTokenPriorityAfterCustomMethods", func(t *testing.T) {
t.Parallel()

// Create a different token for custom header
customKey, customToken := dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
Expand DownExpand Up@@ -98,8 +94,6 @@ func TestRFC6750BearerTokenAuthentication(t *testing.T) {
})

t.Run("InvalidBearerToken", func(t *testing.T) {
t.Parallel()

req := httptest.NewRequest("GET", "/test", nil)
req.Header.Set("Authorization", "Bearer invalid-token")

Expand All@@ -118,8 +112,6 @@ func TestRFC6750BearerTokenAuthentication(t *testing.T) {
})

t.Run("ExpiredBearerToken", func(t *testing.T) {
t.Parallel()

// Create an expired token
_, expiredToken := dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
Expand All@@ -144,8 +136,6 @@ func TestRFC6750BearerTokenAuthentication(t *testing.T) {
})

t.Run("MissingBearerToken", func(t *testing.T) {
t.Parallel()

req := httptest.NewRequest("GET", "/test", nil)
// No authentication provided

Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp