CVE-2022-39378 - Discourse Badge Leaks Sensitive Topic Titles – A Deep Dive
Discourse is a popular open-source platform for community discussion, powering forums for companies, nonprofits, games, and hobbyists alike. But in late 2022, a privacy vulnerability came to light: CVE-2022-39378. This issue exposed the possibility of leaking *topic titles* from private or restricted forums—potentially revealing confidential or sensitive information to any user.
In this post, we'll break down what CVE-2022-39378 is, how it happened, inclusion of code snippets for context, the risks it introduces, and how to make sure you’re protected. We’ll reference the official advisories as well.
Let’s start with the way badges and topics work in Discourse
- Badges are rewards for different activity thresholds (e.g., “First Post”, “Reader”, “Nice Reply”).
- Some badges may be tied to specific *topics* or posts—like a badge for starting a certain kind of discussion.
From GitHub Security Advisory
> Under certain conditions, a user badge may have been awarded based on a user's activity in a topic with restricted access. Before this vulnerability was disclosed, the topic title of the topic associated with the user badge may be viewed by any user.
So, while the post content and topic itself remained restricted, the *title* could leak just by viewing the badge page.
Imagine a private moderator topic titled: “Confidential: Upcoming Restructuring Plan”
- A badge awarded for posting in this topic would, when viewed on a public user profile, reveal the above title to all users—even those who are not moderators.
How Was the Data Leaked?
Let’s illustrate with simplified Ruby/Rails-like pseudocode, as Discourse is a Rails app.
# Old code (Vulnerable):
badges.each do |badge|
badge_topic = Topic.find_by(id: badge.topic_id)
badge_title = badge_topic.title # This title is shown to any user!
puts "Badge for: #{badge_title}" # Potential leaking point
end
Here, the code fetches and shows the title for any badge’s associated topic, *without checking* if the current viewer has permission to see that topic.
See earned badges.
3. Reveal sensitive topic titles in the badge description—even for topics they have no access to view.
View the user's badge page.
3. Note the titles of the topics associated with those badges—even if you cannot see the actual private topic or its contents.
No code or hacking skills needed—just a click. That’s why this is sometimes called an *Insecure Direct Object Reference (IDOR)*.
Example Badge Display (HTML Output for Badge Page)
<ul>
<% @user.badges.each do |badge| %>
<li>
<%= badge.name %> earned for:
<span><%= badge.topic.title %></span> <!-- Here lies the leak -->
</li>
<% end %>
</ul>
If the controller or view logic doesn't check permissions
def show
@user = User.find(params[:id])
@badges = @user.badges.includes(:topic)
render :show
end
Everyone running Discourse before the patched versions is potentially at risk, especially sites with
- Private categories for staff/moderators/company partners
What’s The Fix?
The Discourse team patched this bug very quickly. The solution is to verify a user has permission to see a topic *before* exposing the associated title:
# Patched code:
badges.each do |badge|
badge_topic = Topic.find_by(id: badge.topic_id)
if current_user.can_see_topic?(badge_topic)
badge_title = badge_topic.title
puts "Badge for: #{badge_title}"
else
badge_title = "[Private Topic]"
puts "Badge for: #{badge_title}"
end
end
Now, if the viewer isn’t authorized, the title won’t be revealed.
Official Patch Reference
- GitHub Commit: add security check for badge topic
- Discourse Meta security advisory *(copy the link if needed)*
No. According to the official advisory
> There are currently no known workarounds available.
Updating Discourse is the only way to fix the issue.
Limit badge associations with private content unless necessary.
Privacy and information disclosure bugs like CVE-2022-39378 remind us how even small oversights in logic can lead to major data leaks.
References
- CVE-2022-39378 Official Advisory on GitHub
- Discourse Patch Pull Request
- Discourse Security Announcements
If you are a community manager or developer, take a moment to check your Discourse forums and update today!
Timeline
Published on: 11/02/2022 17:15:00 UTC
Last modified on: 11/04/2022 14:21:00 UTC