mirror of
https://github.com/go-gitea/gitea
synced 2025-12-07 13:28:25 +00:00
Partially backport #32473. LFS related changes are not in 1.22, so skip them. 1. Ignore non-existing repos during migrations 2. Improve ReadBatchLine's comment 3. Use `X-Gitea-Internal-Auth` header for internal API calls and make the comparing constant time (it wasn't a serous problem because in a real world it's nearly impossible to timing-attack the token, but indeed security related and good to fix and backport) 4. Fix route mock nil check
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
package private
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -18,22 +19,23 @@ import (
|
||||
chi_middleware "github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
|
||||
// CheckInternalToken check internal token is set
|
||||
func CheckInternalToken(next http.Handler) http.Handler {
|
||||
func authInternal(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
tokens := req.Header.Get("Authorization")
|
||||
fields := strings.SplitN(tokens, " ", 2)
|
||||
if setting.InternalToken == "" {
|
||||
log.Warn(`The INTERNAL_TOKEN setting is missing from the configuration file: %q, internal API can't work.`, setting.CustomConf)
|
||||
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if len(fields) != 2 || fields[0] != "Bearer" || fields[1] != setting.InternalToken {
|
||||
|
||||
tokens := req.Header.Get("X-Gitea-Internal-Auth") // TODO: use something like JWT or HMAC to avoid passing the token in the clear
|
||||
after, found := strings.CutPrefix(tokens, "Bearer ")
|
||||
authSucceeded := found && subtle.ConstantTimeCompare([]byte(after), []byte(setting.InternalToken)) == 1
|
||||
if !authSucceeded {
|
||||
log.Debug("Forbidden attempt to access internal url: Authorization header: %s", tokens)
|
||||
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
|
||||
} else {
|
||||
next.ServeHTTP(w, req)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -51,7 +53,7 @@ func bind[T any](_ T) any {
|
||||
func Routes() *web.Route {
|
||||
r := web.NewRoute()
|
||||
r.Use(context.PrivateContexter())
|
||||
r.Use(CheckInternalToken)
|
||||
r.Use(authInternal)
|
||||
// Log the real ip address of the request from SSH is really helpful for diagnosing sometimes.
|
||||
// Since internal API will be sent only from Gitea sub commands and it's under control (checked by InternalToken), we can trust the headers.
|
||||
r.Use(chi_middleware.RealIP)
|
||||
|
||||
Reference in New Issue
Block a user