Summary
A malicious remote server can register to a Kitsune server an ActivityPub object with an arbitrary domain name by responding with an object with crafted id
/attributedTo
properties.
Details
Fetcher
doesn't check that the authority part of the fetched ActivityPub object's id
and attributedTo
match that of the remote server.
Section 3.1. of the W3C Recommendation of ActivityPub specifies that the object identifier, if exists, must (not the upper-cased MUST
though) be:
Publicly dereferencable URIs, such as HTTPS URIs, with their authority belonging to that of their originating server.
The Fetcher
methods are used in GET /v2/search
of Mastodon API, allowing the caller to make the Kitsune server register the crafted object.
PoC (WIP)
The following test shouldn't pass, but it currently passes. It shows that the fetcher believes whatever id
the remote server returned regardless of its authority part.
diff --git a/kitsune/src/activitypub/fetcher.rs b/kitsune/src/activitypub/fetcher.rs
index b359623..3421663 100644
--- a/kitsune/src/activitypub/fetcher.rs
+++ b/kitsune/src/activitypub/fetcher.rs
@@ -488,6 +488,39 @@ mod test {
.await;
}
+ #[tokio::test]
+ #[serial_test::serial]
+ async fn check_id_authority_poc() {
+ database_test(|db_pool| async move {
+ let client = service_fn(|req: Request<_>| {
+ assert_ne!(req.uri().host(), Some("corteximplant.com"));
+ handle(req)
+ });
+ let client = Client::builder().service(client);
+
+ let fetcher = Fetcher::builder()
+ .client(client)
+ .db_pool(db_pool)
+ .embed_client(None)
+ .federation_filter(
+ FederationFilterService::new(&FederationFilterConfiguration::Deny {
+ domains: Vec::new(),
+ })
+ .unwrap(),
+ )
+ .search_service(NoopSearchService)
+ .post_cache(Arc::new(NoopCache.into()))
+ .user_cache(Arc::new(NoopCache.into()))
+ .build();
+
+ assert!(fetcher
+ .fetch_actor("https://example.com/users/0x0".into())
+ .await
+ .is_ok());
+ })
+ .await;
+ }
+
#[tokio::test]
#[serial_test::serial]
async fn federation_allow() {
Impact
The vulnerability most notably allows an attacker disguise themselves as arbitrary user and make posts, by making crafted objects with their atteibutedTo
value being the victim user's ID. This might also allow an attacker to update the profile of arbitrary user.
Summary
A malicious remote server can register to a Kitsune server an ActivityPub object with an arbitrary domain name by responding with an object with crafted
id
/attributedTo
properties.Details
Fetcher
doesn't check that the authority part of the fetched ActivityPub object'sid
andattributedTo
match that of the remote server.Section 3.1. of the W3C Recommendation of ActivityPub specifies that the object identifier, if exists, must (not the upper-cased
MUST
though) be:The
Fetcher
methods are used inGET /v2/search
of Mastodon API, allowing the caller to make the Kitsune server register the crafted object.PoC (WIP)
The following test shouldn't pass, but it currently passes. It shows that the fetcher believes whatever
id
the remote server returned regardless of its authority part.Impact
The vulnerability most notably allows an attacker disguise themselves as arbitrary user and make posts, by making crafted objects with their
atteibutedTo
value being the victim user's ID. This might also allow an attacker to update the profile of arbitrary user.