mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-05-20 01:36:37 +00:00
fix(federation): verify host header of requsets
This commit is contained in:
parent
5b6c702f41
commit
355b31a6a9
2 changed files with 32 additions and 4 deletions
|
|
@ -5,6 +5,7 @@ package activitypub
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"forgejo.org/modules/log"
|
||||
"forgejo.org/modules/setting"
|
||||
|
|
@ -15,6 +16,22 @@ import (
|
|||
)
|
||||
|
||||
func verifyHTTPSignature(ctx app_context.APIContext) (authenticated bool, err error) {
|
||||
// Verify that the canonical domain for federation is accessed regardless of
|
||||
// if signatures are actually checked or not.
|
||||
|
||||
// This check does not cover the instance actor but that does not contain any
|
||||
// potentially private information which should only be accessed via the
|
||||
// canonical instance domain.
|
||||
appURL, err := url.Parse(setting.AppURL)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if ctx.Req.Host != appURL.Host {
|
||||
log.Error("%s", ctx.Req.Host)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if !setting.Federation.SignatureEnforced {
|
||||
return true, nil
|
||||
}
|
||||
|
|
@ -48,9 +65,9 @@ func ReqHTTPSignature() func(ctx *app_context.APIContext) {
|
|||
return func(ctx *app_context.APIContext) {
|
||||
if authenticated, err := verifyHTTPSignature(*ctx); err != nil {
|
||||
log.Warn("verifyHttpSignature failed: %v", err)
|
||||
ctx.Error(http.StatusBadRequest, "reqSignature", "request signature verification failed")
|
||||
ctx.Error(http.StatusBadRequest, "reqSignature", "request verification failed")
|
||||
} else if !authenticated {
|
||||
ctx.Error(http.StatusForbidden, "reqSignature", "request signature verification failed")
|
||||
ctx.Error(http.StatusForbidden, "reqSignature", "request verification failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func TestFederationHttpSigValidation(t *testing.T) {
|
|||
|
||||
onApplicationRun(t, func(t *testing.T, u *url.URL) {
|
||||
userID := 2
|
||||
userURL := fmt.Sprintf("%sapi/v1/activitypub/user-id/%d", u, userID)
|
||||
userURL := fmt.Sprintf("%sapi/v1/activitypub/user-id/%d", setting.AppURL, userID)
|
||||
|
||||
user1 := unittest.AssertExistsAndLoadBean(t, &user.User{ID: 1})
|
||||
|
||||
|
|
@ -94,6 +94,17 @@ func TestFederationHttpSigValidation(t *testing.T) {
|
|||
req := NewRequest(t, "GET", userURL)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
// Request with wrong host header, this should always be checked, even if
|
||||
// signature validation is disabled.
|
||||
|
||||
// The URL passed from the testing function does point to the correct
|
||||
// instance but with the wrong host (localhost vs 127.0.0.1).
|
||||
wrongHostUserURL := fmt.Sprintf("%sapi/v1/activitypub/user-id/%d", u, userID)
|
||||
t.Run("WrongHostHeader", func(t *testing.T) {
|
||||
req := NewRequest(t, "GET", wrongHostUserURL)
|
||||
MakeRequest(t, req, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +152,7 @@ func TestFederationAllRoutesCovered(t *testing.T) {
|
|||
}
|
||||
|
||||
resp := MakeRequest(t, req, http.StatusBadRequest)
|
||||
assert.Contains(t, resp.Body.String(), "request signature verification failed")
|
||||
assert.Contains(t, resp.Body.String(), "request verification failed")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue