mirror of
https://github.com/discourse/discourse.git
synced 2026-03-04 01:15:08 +08:00
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
31 lines
916 B
Ruby
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
|