Coordinated Disclosure Timeline
- 2025-12-09: Reported via Email to the maintainer.
- 2025-12-22: Issues were fixed on main branch (commits 9a29bba and 41d6d02)
Summary
Lobsters contained issues allowing unauthenticated users to create new domain entries and permitting Mastodon accounts to be linked to users without proper validation.
Project
Lobsters
Tested Version
Details
Issue 1: Missing check for linking Mastodon account to user (GHSL-2025-126)
A Cross-Site Request Forgery (CSRF) vulnerability existed in the Lobsters application’s Mastodon OAuth integration that allowed attackers to link a victim’s Lobsters account to an attacker-controlled Mastodon account without the victim’s knowledge or consent. This was possible because the OAuth callback flow lacked state parameter validation and session binding, enabling unauthorized modification of user account associations through a simple GET request. Note: Only Lobsters instances that had Mastodon linking enabled were affected by this vulnerability.
Issue: No session state is created (e.g., session[:mastodon_state] = SecureRandom.hex) and included in the URL for the OAuth instance:
def oauth_auth_url
"https://#{name}/oauth/authorize?response_type=code&client_id=#{client_id}&scope=read:accounts&redirect_uri=#{CGI.escape(redirect_uri)}"
end
Consequently, the state cannot be validated in the mastodon_callback method:
def mastodon_callback
if params[:code].blank?
flash[:error] = "Invalid OAuth state"
return redirect_to settings_path
end
[..]
end
Impact
This vulnerability allows attackers to link to any Mastodon profile from the Lobsters profile page of their victims. It might enable further impact should Lobsters expand the Mastodon integration.
CWEs
- CWE-352: Cross-Site Request Forgery (CSRF)
Resources
- OAuth 2.0 RFC 6749 Section 10.12: CSRF Protection
Issue 2: Unauthenticated users can create new domain entries (GHSL-2025-127)
An authorization bypass vulnerability existed in Lobsters that allowed unauthenticated users to create Domain records via the POST /domains endpoint. The vulnerability can lead to data pollution and potentially the disruption of moderation workflows. Attackers might use it to (partially) disguise a spam/phishing domain as a trusted domain.
The vulnerability stems from inconsistent application of authorization checks in the DomainsController. While the :edit and :update actions are protected with before_action :require_logged_in_moderator, the :create action lacks any authentication or authorization requirement.
Relevant Code Locations
1. Route Definition (config/routes.rb:75)
resources :domains, only: [:create, :edit, :update]
Exposes POST /domains for the create action without restrictions.
2. Controller Authorization (app/controllers/domains_controller.rb:3-6)
before_action :require_logged_in_moderator, only: [:edit, :update]
The before_action filter only applies to :edit and :update, explicitly excluding :create.
3. Unprotected Create Action (app/controllers/domains_controller.rb:7-18)
def create
@domain = Domain.where(:domain => params[:new_domain]).first_or_initialize
# ... no authorization check ...
@domain.save
end
4. Permitted Parameters (app/controllers/domains_controller.rb:35-36)
params.require(:domain).permit(:banned_reason, :selector, :replacement)
Impact
The vulnerability can lead to data pollution and potentially the disruption of moderation workflows. Attackers might use this vulnerability to disguise a malicious domain as a trusted domain.
CWEs
- CWE-862: Missing Authorization
Credit
This issue was discovered with the GitHub Security Lab Taskflow Agent and manually verified by GHSL team members @p- (Peter Stöckli) and @m-y-mo (Man Yue Mo).
Contact
You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2025-126 or GHSL-2025-127 in any communication regarding these issues.