GHSA-95q8-x6r6-672m - Lemmy may expose private community data through community, saved, liked, and mod

📡 GitHub-Advisory · 2026-05-06

GHSA-95q8-x6r6-672m - Lemmy may expose private community data through community, saved, liked, and mod

GHSA-95q8-x6r6-672m MEDIUM rust/lemmy_api

CVE:

Summary

Lemmy applies private-community checks in PostView and CommentView, but several adjacent API views skip the accepted-follower filter. Bob, a registered user who is not an accepted follower, can read private community sidebar and summary fields. Alice, a former accepted follower, can still read saved and liked private post bodies after she leaves. An unauthenticated visitor can read private community metadata and removed private post names through the modlog.

Details

CommunityView::read() and CommunityQuery::list() call visible_communities_only(), but they do not add the private-community filter used by post and comment reads:

query = my_local_user.visible_communities_only(query);
query.first(conn).await.with_lemmy_type(LemmyErrorType::NotFound)

PersonSavedCombinedQuery::list() and PersonLikedCombinedQuery::list() join community_actions, but they only filter by the requesting person id. They do not require community_actions.follow_state = Accepted when the community has visibility = Private.

The modlog query returns ListingType::All without a visibility predicate:

query = match self.listing_type.unwrap_or(ListingType::All) {
  ListingType::All => query,

The control paths show the expected check. PostView::read() and CommentView::read() both filter private communities to accepted followers:

community::visibility
  .ne(CommunityVisibility::Private)
  .or(community_actions::follow_state.eq(CommunityFollowerState::Accepted))

Proof of Concept

The following script reproduces the leak against a fresh Lemmy instance. Tested against dessalines/lemmy:nightly with the default setup account from the sample config. The script opens registration so it can create Alice and Bob.

import requests, random, string

BASE = "http://127.0.0.1:8536/api/v4"  # change to the target Lemmy URL
ADMIN_USER = "lemmy"
ADMIN_PASS = "lemmylemmy"
PASSWORD = "Password123456!"

def req(method, path

📌 来源: GitHub-Advisory | 📅 2026-05-06

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)