From a96209a3333a45ccd236c84c1abd5c70e5543029 Mon Sep 17 00:00:00 2001 From: Ryan Barrett Date: Wed, 7 Aug 2024 13:09:03 -0700 Subject: [PATCH] AP inbox: check that activity is public before verifying signature --- activitypub.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/activitypub.py b/activitypub.py index 3076361..1d44d11 100644 --- a/activitypub.py +++ b/activitypub.py @@ -1019,8 +1019,9 @@ def inbox(protocol=None, id=None): # do we support this object type? # (this logic is duplicated in Protocol.check_supported) + object = as1.get_object(activity) if type := activity.get('type'): - inner_type = as1.object_type(as1.get_object(activity)) or '' + inner_type = as1.object_type(object) or '' if (type not in ActivityPub.SUPPORTED_AS2_TYPES or (type in as2.CRUD_VERBS and inner_type @@ -1038,6 +1039,19 @@ def inbox(protocol=None, id=None): logger.info(f'Already seen this activity {id}') return '', 204 + # check that this activity is public. only do this for creates, not likes, + # follows, or other activity types, since Mastodon doesn't currently mark + # those as explicitly public. Use as2's is_public instead of as1's because + # as1's interprets unlisted as true. + # TODO: move this to Protocol + to_cc = set(as1.get_ids(object, 'to') + as1.get_ids(activity, 'cc') + + as1.get_ids(object, 'to') + as1.get_ids(object, 'cc')) + if (type == 'Create' and not as2.is_public(activity, unlisted=False) + # DM to one of our protocol bot users + and not (len(to_cc) == 1 and to_cc.pop() in BOT_ACTOR_AP_IDS)): + logger.info('Dropping non-public activity') + return 'OK' + # check actor, signature, auth actor = as1.get_object(activity, 'actor') actor_id = actor.get('id') @@ -1061,20 +1075,6 @@ def inbox(protocol=None, id=None): if authed_as != actor_id and activity.get('signature'): error(f"Ignoring LD Signature, sorry, we can't verify those yet. https://github.com/snarfed/bridgy-fed/issues/566", status=202) - # check that this activity is public. only do this for creates, not likes, - # follows, or other activity types, since Mastodon doesn't currently mark - # those as explicitly public. Use as2's is_public instead of as1's because - # as1's interprets unlisted as true. - # TODO: move this to Protocol - object = as1.get_object(activity) - to_cc = set(as1.get_ids(object, 'to') + as1.get_ids(activity, 'cc') + - as1.get_ids(object, 'to') + as1.get_ids(object, 'cc')) - if (type == 'Create' and not as2.is_public(activity, unlisted=False) - # DM to one of our protocol bot users - and not (len(to_cc) == 1 and to_cc.pop() in BOT_ACTOR_AP_IDS)): - logger.info('Dropping non-public activity') - return 'OK' - if type == 'Follow': # rendered mf2 HTML proxy pages (in render.py) fall back to redirecting # to the follow's AS2 id field, but Mastodon's Accept ids are URLs that