forked from gitea/gitea
		
	Deprecate query string auth tokens (#28390)
## Changes - Add deprecation warning to `Token` and `AccessToken` authentication methods in swagger. - Add deprecation warning header to API response. Example: ``` HTTP/1.1 200 OK ... Warning: token and access_token API authentication is deprecated ... ``` - Add setting `DISABLE_QUERY_AUTH_TOKEN` to reject query string auth tokens entirely. Default is `false` ## Next steps - `DISABLE_QUERY_AUTH_TOKEN` should be true in a subsequent release and the methods should be removed in swagger - `DISABLE_QUERY_AUTH_TOKEN` should be removed and the implementation of the auth methods in question should be removed ## Open questions - Should there be further changes to the swagger documentation? Deprecation is not yet supported for security definitions (coming in [OpenAPI Spec version 3.2.0](https://github.com/OAI/OpenAPI-Specification/issues/2506)) - Should the API router logger sanitize urls that use `token` or `access_token`? (This is obviously an insufficient solution on its own) --------- Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
		
							parent
							
								
									baea205675
								
							
						
					
					
						commit
						4e879fed90
					
				| @ -492,6 +492,11 @@ INTERNAL_TOKEN= | ||||
| ;; Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. | ||||
| ;; This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security. | ||||
| ;SUCCESSFUL_TOKENS_CACHE_SIZE = 20 | ||||
| ;; | ||||
| ;; Reject API tokens sent in URL query string (Accept Header-based API tokens only). This avoids security vulnerabilities | ||||
| ;; stemming from cached/logged plain-text API tokens. | ||||
| ;; In future releases, this will become the default behavior | ||||
| ;DISABLE_QUERY_AUTH_TOKEN = false | ||||
| 
 | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
|  | ||||
| @ -34,6 +34,7 @@ var ( | ||||
| 	PasswordHashAlgo                   string | ||||
| 	PasswordCheckPwn                   bool | ||||
| 	SuccessfulTokensCacheSize          int | ||||
| 	DisableQueryAuthToken              bool | ||||
| 	CSRFCookieName                     = "_csrf" | ||||
| 	CSRFCookieHTTPOnly                 = true | ||||
| ) | ||||
| @ -157,4 +158,11 @@ func loadSecurityFrom(rootCfg ConfigProvider) { | ||||
| 			PasswordComplexity = append(PasswordComplexity, name) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: default value should be true in future releases | ||||
| 	DisableQueryAuthToken = sec.Key("DISABLE_QUERY_AUTH_TOKEN").MustBool(false) | ||||
| 
 | ||||
| 	if !DisableQueryAuthToken { | ||||
| 		log.Warn("Enabling Query API Auth tokens is not recommended. DISABLE_QUERY_AUTH_TOKEN will default to true in gitea 1.23 and will be removed in gitea 1.24.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -35,10 +35,12 @@ | ||||
| //	     type: apiKey | ||||
| //	     name: token | ||||
| //	     in: query | ||||
| //	     description: This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead. | ||||
| //	AccessToken: | ||||
| //	     type: apiKey | ||||
| //	     name: access_token | ||||
| //	     in: query | ||||
| //	     description: This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead. | ||||
| //	AuthorizationHeaderToken: | ||||
| //	     type: apiKey | ||||
| //	     name: Authorization | ||||
| @ -788,6 +790,13 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIC | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // check for and warn against deprecated authentication options | ||||
| func checkDeprecatedAuthMethods(ctx *context.APIContext) { | ||||
| 	if ctx.FormString("token") != "" || ctx.FormString("access_token") != "" { | ||||
| 		ctx.Resp.Header().Set("Warning", "token and access_token API authentication is deprecated and will be removed in gitea 1.23. Please use AuthorizationHeaderToken instead. Existing queries will continue to work but without authorization.") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Routes registers all v1 APIs routes to web application. | ||||
| func Routes() *web.Route { | ||||
| 	m := web.NewRoute() | ||||
| @ -806,6 +815,8 @@ func Routes() *web.Route { | ||||
| 	} | ||||
| 	m.Use(context.APIContexter()) | ||||
| 
 | ||||
| 	m.Use(checkDeprecatedAuthMethods) | ||||
| 
 | ||||
| 	// Get user from session if logged in. | ||||
| 	m.Use(apiAuth(buildAuthGroup())) | ||||
| 
 | ||||
|  | ||||
| @ -14,6 +14,7 @@ import ( | ||||
| 	auth_model "code.gitea.io/gitea/models/auth" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| 	"code.gitea.io/gitea/services/auth/source/oauth2" | ||||
| @ -62,14 +63,19 @@ func (o *OAuth2) Name() string { | ||||
| // representing whether the token exists or not | ||||
| func parseToken(req *http.Request) (string, bool) { | ||||
| 	_ = req.ParseForm() | ||||
| 	// Check token. | ||||
| 	if token := req.Form.Get("token"); token != "" { | ||||
| 		return token, true | ||||
| 	} | ||||
| 	// Check access token. | ||||
| 	if token := req.Form.Get("access_token"); token != "" { | ||||
| 		return token, true | ||||
| 	if !setting.DisableQueryAuthToken { | ||||
| 		// Check token. | ||||
| 		if token := req.Form.Get("token"); token != "" { | ||||
| 			return token, true | ||||
| 		} | ||||
| 		// Check access token. | ||||
| 		if token := req.Form.Get("access_token"); token != "" { | ||||
| 			return token, true | ||||
| 		} | ||||
| 	} else if req.Form.Get("token") != "" || req.Form.Get("access_token") != "" { | ||||
| 		log.Warn("API token sent in query string but DISABLE_QUERY_AUTH_TOKEN=true") | ||||
| 	} | ||||
| 
 | ||||
| 	// check header token | ||||
| 	if auHead := req.Header.Get("Authorization"); auHead != "" { | ||||
| 		auths := strings.Fields(auHead) | ||||
|  | ||||
							
								
								
									
										2
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							| @ -24046,6 +24046,7 @@ | ||||
|   }, | ||||
|   "securityDefinitions": { | ||||
|     "AccessToken": { | ||||
|       "description": "This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.", | ||||
|       "type": "apiKey", | ||||
|       "name": "access_token", | ||||
|       "in": "query" | ||||
| @ -24078,6 +24079,7 @@ | ||||
|       "in": "header" | ||||
|     }, | ||||
|     "Token": { | ||||
|       "description": "This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.", | ||||
|       "type": "apiKey", | ||||
|       "name": "token", | ||||
|       "in": "query" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jack Hay
						Jack Hay