component AP gateway: work around encoding bug in Mastodon:

Mastodon in wrongly unquoting URL path in `(request-target)`, and thus Libervia was doing
the same to check signature. However that doesn't work with Pleroma which is using the
path value used in the request (percent-encoded), and thus Pleroma signature were
rejected.

To work around that, signature is first checked without unquoting, and if this fails a new
check is done with unquoting.

Bug has been reported at https://github.com/mastodon/mastodon/issues/18871

rel 371
This commit is contained in:
Goffi 2022-08-31 17:07:03 +02:00
commit 1f03f3ee14

View file

@ -980,7 +980,7 @@ class HTTPAPGServer(web_resource.Resource):
for to_sign in signed_headers:
if to_sign == "(request-target)":
method = request.method.decode().lower()
uri = parse.unquote(request.uri.decode())
uri = request.uri.decode()
headers[to_sign] = f"{method} /{uri.lstrip('/')}"
elif to_sign in ("(created)", "(expires)"):
if algorithm != HS2019:
@ -1070,11 +1070,24 @@ class HTTPAPGServer(web_resource.Resource):
if created > limit_ts:
raise exceptions.EncryptionError("Signature has expired")
return await self.apg.checkSignature(
sign_data["signature"],
key_id,
headers
)
try:
return await self.apg.checkSignature(
sign_data["signature"],
key_id,
headers
)
except exceptions.EncryptionError:
method, url = headers["(request-target)"].rsplit(' ', 1)
headers["(request-target)"] = f"{method} {parse.unquote(url)}"
log.debug(
"Using workaround for (request-target) encoding bug in signature, "
"see https://github.com/mastodon/mastodon/issues/18871"
)
return await self.apg.checkSignature(
sign_data["signature"],
key_id,
headers
)
def render(self, request):
request.setHeader("server", VERSION)