GHSA-95q8-x6r6-672m - Lemmy may expose private community data through community, saved, liked, and mod
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