From a45c1ce152011e8fe25eb1d25594ac5705f65404 Mon Sep 17 00:00:00 2001 From: rako Date: Fri, 28 Nov 2025 10:37:49 +0100 Subject: Fix user matching In order to be a proper prefix, the actor url must end with a '/' otherwise it can match another user that starts with the same prefix: for example 'testuser' will match anything made by 'testuser2' --- activitypub.c | 14 +++++++------- data.c | 8 ++++---- html.c | 6 +++--- mastoapi.c | 4 ++-- rss.c | 2 +- upgrade.c | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/activitypub.c b/activitypub.c index 2c0fa2e..90230d8 100644 --- a/activitypub.c +++ b/activitypub.c @@ -779,7 +779,7 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) object_get(object, &obj); /* if it's about one of our posts, accept it */ - if (xs_startswith(object, snac->actor)) + if (is_msg_mine(snac, object)) return 2; /* blocked by hashtag? */ @@ -1242,7 +1242,7 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, if (xs_match(type, "Like|Announce|EmojiReact")) { /* if it's not an admiration about something by us, done */ - if (xs_is_null(objid) || !xs_startswith(objid, snac->actor)) + if (xs_is_null(objid) || !is_msg_mine(snac, objid)) return; /* if it's an announce by our own relay, done */ @@ -1267,7 +1267,7 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, return; /* if it's not ours and we didn't vote, discard */ - if (!xs_startswith(poll_id, snac->actor) && !was_question_voted(snac, poll_id)) + if (!is_msg_mine(snac, poll_id) && !was_question_voted(snac, poll_id)) return; } @@ -2792,10 +2792,10 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) if (xs_is_null(object)) snac_log(snac, xs_fmt("malformed message: no 'id' field")); else - if (is_muted(snac, actor) && !xs_startswith(object, snac->actor)) + if (is_muted(snac, actor) && !is_msg_mine(snac, object)) snac_log(snac, xs_fmt("dropped 'Announce' from muted actor %s", actor)); else - if (is_limited(snac, actor) && !xs_startswith(object, snac->actor)) + if (is_limited(snac, actor) && !is_msg_mine(snac, object)) snac_log(snac, xs_fmt("dropped 'Announce' from limited actor %s", actor)); else { xs *a_msg = NULL; @@ -2903,7 +2903,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) snac_log(snac, xs_fmt("malformed message: no 'id' field")); else if (object_here(object)) { - if (xs_startswith(object, srv_baseurl) && !xs_startswith(object, actor)) + if (xs_startswith(object, srv_baseurl) && !is_msg_mine(snac, object)) snac_log(snac, xs_fmt("ignored incorrect 'Delete' %s %s", actor, object)); else { timeline_del(snac, object); @@ -3716,7 +3716,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, const char *type = xs_dict_get(i, "type"); const char *id = xs_dict_get(i, "id"); - if (type && id && strcmp(type, "Note") == 0 && xs_startswith(id, snac.actor)) { + if (type && id && strcmp(type, "Note") == 0 && is_msg_mine(&snac, id)) { if (is_msg_public(i)) { xs *c_msg = msg_create(&snac, i); list = xs_list_append(list, c_msg); diff --git a/data.c b/data.c index c2fdccb..688d2e3 100644 --- a/data.c +++ b/data.c @@ -1467,7 +1467,7 @@ void timeline_update_indexes(snac *snac, const char *id) { object_user_cache_add(snac, id, "private"); - if (xs_startswith(id, snac->actor)) { + if (is_msg_mine(snac, id)) { xs *msg = NULL; if (valid_status(object_get(id, &msg))) { @@ -1927,7 +1927,7 @@ int pin(snac *user, const char *id) { int ret = -2; - if (xs_startswith(id, user->actor)) { + if (is_msg_mine(user, id)) { if (is_pinned(user, id)) ret = -3; else @@ -3527,7 +3527,7 @@ void enqueue_output(snac *snac, const xs_dict *msg, const xs_str *inbox, int retries, int p_status) /* enqueues an output message to an inbox */ { - if (xs_startswith(inbox, snac->actor)) { + if (is_msg_mine(snac, inbox)) { snac_debug(snac, 1, xs_str_new("refusing enqueue to myself")); return; } @@ -4055,7 +4055,7 @@ void delete_purged_posts(snac *user, int days) if (xs_is_dict(msg)) { const char *id = xs_dict_get(msg, "id"); - if (xs_is_string(id) && xs_startswith(id, user->actor)) { + if (xs_is_string(id) && is_msg_mine(user, id)) { xs *d_msg = msg_delete(user, id); enqueue_message(user, d_msg); diff --git a/html.c b/html.c index 12d269a..d6223b9 100644 --- a/html.c +++ b/html.c @@ -1898,7 +1898,7 @@ xs_html *html_entry_controls(snac *user, const char *actor, xs_html_attr("name", "redir"), xs_html_attr("value", redir)))); - if (!xs_startswith(id, user->actor)) { + if (!is_msg_mine(user, id)) { if (xs_list_in(likes, user->md5) == -1) { /* not already liked; add button */ xs_html_add(form, @@ -2426,7 +2426,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, if (read_only) closed = 1; /* non-identified page; show as closed */ else - if (user && xs_startswith(id, user->actor)) + if (user && is_msg_mine(user, id)) closed = 1; /* we questioned; closed for us */ else if (user && was_question_voted(user, id)) @@ -5022,7 +5022,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, } else { /* delete an entry */ - if (xs_startswith(id, snac.actor) && !is_draft(&snac, id)) { + if (is_msg_mine(&snac, id) && !is_draft(&snac, id)) { /* it's a post by us: generate a delete */ xs *msg = msg_delete(&snac, id); diff --git a/mastoapi.c b/mastoapi.c index 94912f1..acb95a0 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1919,7 +1919,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, /* add only posts by the author */ if (!xs_is_null(msg_id) && strcmp(xs_dict_get(msg, "type"), "Note") == 0 && - xs_startswith(xs_dict_get(msg, "id"), snac2.actor) && is_msg_public(msg)) { + is_msg_mine(&snac2, xs_dict_get(msg, "id")) && is_msg_public(msg)) { /* if max_id is set, skip entries until we find it */ if (skip_until_max) { @@ -3824,7 +3824,7 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path, if (valid_status(object_get_by_md5(p, &obj))) { const char *id = xs_dict_get(obj, "id"); - if (xs_is_string(id) && xs_startswith(id, snac.actor)) { + if (xs_is_string(id) && is_msg_mine(&snac, id)) { xs *out = mastoapi_status(&snac, obj); xs *msg = msg_delete(&snac, id); diff --git a/rss.c b/rss.c index 6e77205..6124e7a 100644 --- a/rss.c +++ b/rss.c @@ -59,7 +59,7 @@ xs_str *rss_from_timeline(snac *user, const xs_list *timeline, const char *content = xs_dict_get(msg, "content"); const char *published = xs_dict_get(msg, "published"); - if (user && !xs_startswith(id, user->actor)) + if (user && !is_msg_mine(user, id)) continue; if (!id || !content || !published) diff --git a/upgrade.c b/upgrade.c index 87ddfc8..9e0ae6e 100644 --- a/upgrade.c +++ b/upgrade.c @@ -213,7 +213,7 @@ int snac_upgrade(xs_str **error) object_add_ow(id, o); /* if it's from us, add to public */ - if (xs_startswith(id, snac.actor)) { + if (is_msg_mine(&snac, id)) { const xs_list *p; const char *v; int c; -- cgit v1.2.3