Mercurial > libervia-backend
comparison sat/plugins/plugin_comp_ap_gateway/http_server.py @ 3884:cea52400623d
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
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 31 Aug 2022 17:07:03 +0200 |
parents | 1bd44367337d |
children | aa7197b67c26 |
comparison
equal
deleted
inserted
replaced
3883:6da749bbf320 | 3884:cea52400623d |
---|---|
978 request.content.seek(0) | 978 request.content.seek(0) |
979 headers = {} | 979 headers = {} |
980 for to_sign in signed_headers: | 980 for to_sign in signed_headers: |
981 if to_sign == "(request-target)": | 981 if to_sign == "(request-target)": |
982 method = request.method.decode().lower() | 982 method = request.method.decode().lower() |
983 uri = parse.unquote(request.uri.decode()) | 983 uri = request.uri.decode() |
984 headers[to_sign] = f"{method} /{uri.lstrip('/')}" | 984 headers[to_sign] = f"{method} /{uri.lstrip('/')}" |
985 elif to_sign in ("(created)", "(expires)"): | 985 elif to_sign in ("(created)", "(expires)"): |
986 if algorithm != HS2019: | 986 if algorithm != HS2019: |
987 raise exceptions.EncryptionError( | 987 raise exceptions.EncryptionError( |
988 f"{to_sign!r} pseudo-header can only be used with {HS2019} " | 988 f"{to_sign!r} pseudo-header can only be used with {HS2019} " |
1068 limit_ts = min(limit_ts, expires) | 1068 limit_ts = min(limit_ts, expires) |
1069 | 1069 |
1070 if created > limit_ts: | 1070 if created > limit_ts: |
1071 raise exceptions.EncryptionError("Signature has expired") | 1071 raise exceptions.EncryptionError("Signature has expired") |
1072 | 1072 |
1073 return await self.apg.checkSignature( | 1073 try: |
1074 sign_data["signature"], | 1074 return await self.apg.checkSignature( |
1075 key_id, | 1075 sign_data["signature"], |
1076 headers | 1076 key_id, |
1077 ) | 1077 headers |
1078 ) | |
1079 except exceptions.EncryptionError: | |
1080 method, url = headers["(request-target)"].rsplit(' ', 1) | |
1081 headers["(request-target)"] = f"{method} {parse.unquote(url)}" | |
1082 log.debug( | |
1083 "Using workaround for (request-target) encoding bug in signature, " | |
1084 "see https://github.com/mastodon/mastodon/issues/18871" | |
1085 ) | |
1086 return await self.apg.checkSignature( | |
1087 sign_data["signature"], | |
1088 key_id, | |
1089 headers | |
1090 ) | |
1078 | 1091 |
1079 def render(self, request): | 1092 def render(self, request): |
1080 request.setHeader("server", VERSION) | 1093 request.setHeader("server", VERSION) |
1081 return super().render(request) | 1094 return super().render(request) |
1082 | 1095 |