From f53e46c721a037c55facb9200106a6b491bf834c Mon Sep 17 00:00:00 2001
From: Anthony Wang <ta180m@proton.me>
Date: Tue, 14 Jun 2022 16:23:08 -0500
Subject: [PATCH] If httpsig verification fails, fix Host header and try again

This fixes a very rare bug when Gitea and another AP server (confirmed to happen with Mastodon) are running on the same machine, Gitea fails to verify incoming HTTP signatures. This is because the other AP server creates the sig with the public Gitea domain as the Host. However, when Gitea receives the request, the Host header is instead localhost, so the signature verification fails. Manually changing the host header to the correct value and trying the verification again fixes the bug.
---
 routers/api/v1/activitypub/reqsignature.go | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go
index f080f4e201..68f034350d 100644
--- a/routers/api/v1/activitypub/reqsignature.go
+++ b/routers/api/v1/activitypub/reqsignature.go
@@ -90,6 +90,16 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, er
 	// 3. Verify the other actor's key
 	algo := httpsig.Algorithm(setting.Federation.Algorithms[0])
 	authenticated = v.Verify(pubKey, algo) == nil
+	if authenticated {
+		return
+	}
+	// 4. When Gitea and the other ActivityPub server are running on the same machine, the Host header is sometimes incorrect
+	r.Header["Host"] = []string{setting.Domain}
+	v, err = httpsig.NewVerifier(r)
+	if err != nil {
+		return
+	}
+	authenticated = v.Verify(pubKey, algo) == nil
 	return
 }