mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
SECURITY: Prevent arbitrary topic custom fields from being set
Why this change? The `PostsController#create` action allows arbitrary topic custom fields to be set by any user that can create a topic. Without any restrictions, this opens us up to potential security issues where plugins may be using topic custom fields in security sensitive areas. What does this change do? 1. This change introduces the `register_editable_topic_custom_field` plugin API which allows plugins to register topic custom fields that are editable either by staff users only or all users. The registered editable topic custom fields are stored in `DiscoursePluginRegistry` and is called by a new method `Topic#editable_custom_fields` which is then used in the `PostsController#create` controller action. When an unpermitted custom fields is present in the `meta_data` params, a 400 response code is returned. 2. Removes all reference to `meta_data` on a topic as it is confusing since we actually mean topic custom fields instead.
This commit is contained in:
committed by
Penar Musaraj
parent
0ed20fe1cd
commit
4cb7472376
@@ -850,8 +850,22 @@ class PostsController < ApplicationController
|
||||
.permit(*permitted)
|
||||
.tap do |allowed|
|
||||
allowed[:image_sizes] = params[:image_sizes]
|
||||
# TODO this does not feel right, we should name what meta_data is allowed
|
||||
allowed[:meta_data] = params[:meta_data]
|
||||
|
||||
if params.has_key?(:meta_data)
|
||||
Discourse.deprecate(
|
||||
"the :meta_data param is deprecated, use the :topic_custom_fields param instead",
|
||||
since: "3.2",
|
||||
drop_from: "3.3",
|
||||
)
|
||||
end
|
||||
|
||||
topic_custom_fields = {}
|
||||
topic_custom_fields.merge!(editable_topic_custom_fields(:meta_data))
|
||||
topic_custom_fields.merge!(editable_topic_custom_fields(:topic_custom_fields))
|
||||
|
||||
if topic_custom_fields.present?
|
||||
allowed[:topic_opts] = { custom_fields: topic_custom_fields }
|
||||
end
|
||||
end
|
||||
|
||||
# Staff are allowed to pass `is_warning`
|
||||
@@ -913,6 +927,25 @@ class PostsController < ApplicationController
|
||||
result.to_h
|
||||
end
|
||||
|
||||
def editable_topic_custom_fields(params_key)
|
||||
if (topic_custom_fields = params[params_key]).present?
|
||||
editable_topic_custom_fields = Topic.editable_custom_fields(guardian)
|
||||
|
||||
if (
|
||||
unpermitted_topic_custom_fields =
|
||||
topic_custom_fields.except(*editable_topic_custom_fields)
|
||||
).present?
|
||||
raise Discourse::InvalidParameters.new(
|
||||
"The following keys in :#{params_key} are not permitted: #{unpermitted_topic_custom_fields.keys.join(", ")}",
|
||||
)
|
||||
end
|
||||
|
||||
topic_custom_fields.permit(*editable_topic_custom_fields).to_h
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
def signature_for(args)
|
||||
+"post##" << Digest::SHA1.hexdigest(
|
||||
args
|
||||
|
||||
Reference in New Issue
Block a user