2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/app/controllers/permalinks_controller.rb
Régis Hanol 250c54e302 SECURITY: prevent permalink redirects from leaking restricted slugs
Permalinks pointing to access-restricted resources (private topics,
categories, posts, or hidden tags) were redirecting users to URLs
containing the resource slug, even when the user didn't have access.

This leaked potentially sensitive information (e.g., private topic
titles) via the redirect Location header and the 404 page's search box.

This fix adds access checks via a new `PermalinkGuardian` module before
redirecting or returning target URLs. If the current user cannot see
the target resource, a 404 is returned instead.

Also fixes `Guardian#can_see_tag?` to properly check hidden tag
visibility instead of always returning true.

Ref - t/172554
2026-01-28 17:11:14 +00:00

31 lines
916 B
Ruby

# frozen_string_literal: true
class PermalinksController < ApplicationController
skip_before_action :check_xhr, :preload_json, only: [:show]
def show
permalink = Permalink.find_by_url(request.fullpath)
raise Discourse::NotFound if permalink.nil?
raise Discourse::NotFound unless guardian.can_see_permalink_target?(permalink)
if permalink.target_url
redirect_to permalink.target_url, status: :moved_permanently, allow_other_host: true
else
raise Discourse::NotFound
end
end
def check
permalink = Permalink.find_by_url(params[:path]) if params[:path].present?
data =
if permalink && guardian.can_see_permalink_target?(permalink)
{ found: true, internal: permalink.internal?, target_url: permalink.target_url }
else
{ found: false, html: build_not_found_page(status: 200) }
end
render json: MultiJson.dump(data)
end
end