Merge pull request 'use constant time check for internal token' (#5719) from earl-warren/forgejo:wip-timing into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5719
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
This commit is contained in:
Earl Warren 2024-10-28 06:14:36 +00:00
commit e08664c56e
2 changed files with 3 additions and 1 deletions

1
release-notes/5719.md Normal file
View file

@ -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.

View file

@ -5,6 +5,7 @@
package private package private
import ( import (
"crypto/subtle"
"net/http" "net/http"
"strings" "strings"
@ -28,7 +29,7 @@ func CheckInternalToken(next http.Handler) http.Handler {
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return 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) log.Debug("Forbidden attempt to access internal url: Authorization header: %s", tokens)
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
} else { } else {