diff --git a/release-notes/5719.md b/release-notes/5719.md new file mode 100644 index 0000000000..19a74825e4 --- /dev/null +++ b/release-notes/5719.md @@ -0,0 +1 @@ +Forgejo generates a token which is used to authenticate web endpoints that are only meant to be used internally, for instance when the SSH daemon is used to push a commit with Git. The verification of this token was not done in constant time and was susceptible to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). A pre-condition for such an attack is the precise measurements of the time for each operation. Since it requires observing the timing of network operations, the issue is mitigated when a Forgejo instance is accessed over the internet because the ISP introduce unpredictable random delays. diff --git a/routers/private/internal.go b/routers/private/internal.go index ede310113c..311f59b60e 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -5,6 +5,7 @@ package private import ( + "crypto/subtle" "net/http" "strings" @@ -28,7 +29,7 @@ func CheckInternalToken(next http.Handler) http.Handler { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } - if len(fields) != 2 || fields[0] != "Bearer" || fields[1] != setting.InternalToken { + if len(fields) != 2 || fields[0] != "Bearer" || subtle.ConstantTimeCompare([]byte(fields[1]), []byte(setting.InternalToken)) == 0 { log.Debug("Forbidden attempt to access internal url: Authorization header: %s", tokens) http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) } else {